tchange md argument to number etc. (which acted only as a flag) to an actual flag. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 012a8a02d5e43c1d4698acf42da61f4429c3ac1f
 (DIR) parent e63027eb68ff7252598003151d238dee8850ad34
 (HTM) Author: rsc <devnull@localhost>
       Date:   Fri, 22 Oct 2004 17:11:30 +0000
       
       change md argument to number etc. (which acted only as a flag)
       tto an actual flag.
       
       buffer underrun check in number
       
       add xdata file for exactly the addressed region
       
       save addr across opens
       
       Diffstat:
         M src/cmd/acme/acme.c                 |      20 ++++++++++++++++++++
         M src/cmd/acme/addr.c                 |      26 ++++++++++++++------------
         M src/cmd/acme/dat.h                  |       2 ++
         M src/cmd/acme/exec.c                 |       4 ++--
         M src/cmd/acme/fns.h                  |       2 +-
         M src/cmd/acme/fsys.c                 |       1 +
         M src/cmd/acme/look.c                 |       4 ++--
         M src/cmd/acme/xfid.c                 |      21 +++++++++++++--------
       
       8 files changed, 55 insertions(+), 25 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/acme/acme.c b/src/cmd/acme/acme.c
       t@@ -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;
       t@@ -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)){
 (DIR) diff --git a/src/cmd/acme/addr.c b/src/cmd/acme/addr.c
       t@@ -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;
        
       t@@ -82,7 +82,7 @@ number(Mntdir *md, Text *t, Range r, int line, int dir, int size, int *evalp)
                        break;
                case Fore:
                        if(q1 > 0)
       -                        while(textreadc(t, q1-1) != '\n')
       +                        while(q1<t->file->b.nc && textreadc(t, q1-1) != '\n')
                                        q1++;
                        q0 = q1;
                        goto Forward;
       t@@ -107,7 +107,7 @@ number(Mntdir *md, Text *t, Range r, int line, int dir, int size, int *evalp)
                return range(q0, q1);
        
            Rescue:
       -        if(md != nil)
       +        if(showerr)
                        warning(nil, "address out of range\n");
                *evalp = FALSE;
                return r;
       t@@ -115,14 +115,15 @@ number(Mntdir *md, Text *t, Range r, int line, int dir, int size, int *evalp)
        
        
        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;
                }
       t@@ -137,16 +138,17 @@ regexp(Mntdir *md, Text *t, Range lim, Range r, Rune *pat, int dir, int *foundp)
                                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;
       t@@ -175,7 +177,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int
                                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;
       t@@ -184,7 +186,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int
                        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 '.':
       t@@ -222,7 +224,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int
                                        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;
       t@@ -255,7 +257,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int
                                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;
       t@@ -263,7 +265,7 @@ address(Mntdir *md, Text *t, Range lim, Range ar, void *a, uint q0, uint q1, int
                        }
                }
                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;
        }
 (DIR) diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h
       t@@ -19,6 +19,7 @@ enum
                QWrdsel,
                QWwrsel,
                QWtag,
       +        QWxdata,
                QMAX,
        };
        
       t@@ -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;
 (DIR) diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c
       t@@ -342,7 +342,7 @@ delcol(Text *et, Text *_0, Text *_1, int _2, int _3, Rune *_4, int _5)
                        return;
                for(i=0; i<c->nw; 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;
                        }
       t@@ -1528,7 +1528,7 @@ Hard:
                if(ret >= 0){
                        if(cpid)
                                sendul(cpid, ret);
       -                threadexits("");
       +                threadexits(nil);
                }
                warning(nil, "exec rc: %r\n");
        
 (DIR) diff --git a/src/cmd/acme/fns.h b/src/cmd/acme/fns.h
       t@@ -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);
 (DIR) diff --git a/src/cmd/acme/fsys.c b/src/cmd/acme/fsys.c
       t@@ -87,6 +87,7 @@ Dirtab dirtabw[]=
                { "rdsel",                QTFILE,                QWrdsel,                0400 },
                { "wrsel",                QTFILE,                QWwrsel,                0200 },
                { "tag",                QTAPPEND,        QWtag,                0600|DMAPPEND },
       +        { "xdata",                QTFILE,                QWxdata,                0600 },
                { nil, }
        };
        
 (DIR) diff --git a/src/cmd/acme/look.c b/src/cmd/acme/look.c
       t@@ -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:
       t@@ -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 */
                }
 (DIR) diff --git a/src/cmd/acme/xfid.c b/src/cmd/acme/xfid.c
       t@@ -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->limit = range(-1,-1);
                                break;
                        case QWevent:
                                if(w->nopen[q]++ == 0){
       t@@ -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;
       t@@ -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;
       t@@ -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);