예제 #1
0
파일: io.c 프로젝트: 4ad/sam
Posn
writeio(File *f)
{
	int m, n;
	Posn p = addr.r.p1;
	char *c;

	while(p < addr.r.p2){
		if(addr.r.p2-p>BLOCKSIZE)
			n = BLOCKSIZE;
		else
			n = addr.r.p2-p;
		if(Fchars(f, genbuf, p, p+n)!=n)
			panic("writef read");
		c = Strtoc(tmprstr(genbuf, n));
		m = strlen(c);
		if (m < n)
			panic("corrupted file");
		if(Write(io, c, m) != m){
			free(c);
			if(p > 0)
				p += n;
			break;
		}
		free(c);
		p += n;
	}
	return p-addr.r.p1;
}
예제 #2
0
파일: xec.c 프로젝트: deadpixi/sam
bool
display(File *f)
{
    Posn p1, p2;
    int np, n;

    p1 = addr.r.p1;
    p2 = addr.r.p2;
    while(p1 < p2){
        np = p2-p1;
        if(np>BLOCKSIZE-1)
            np = BLOCKSIZE-1;
        n = Fchars(f, genbuf, p1, p1+np);
        if(n <= 0)
            panic("display");
        genbuf[n] = 0;
        if(downloaded)
            termwrite(genbuf);
        else
            fprintf(stdout, "%ls", genbuf);
        p1+=n;
    }
    f->dot = addr;
    return true;
}
예제 #3
0
파일: io.c 프로젝트: 4ad/sam
void
writef(File *f)
{
	Rune c;
	Posn n;
	char *name;
	int i, samename, newfile;
	ulong dev, qid;
	long mtime, appendonly, length;

	newfile = 0;
	samename = Strcmp(&genstr, &f->name) == 0;
	name = Strtoc(&f->name);
	i = statfile(name, &dev, &qid, &mtime, 0, 0);
	if(i == -1)
		newfile++;
	else if(samename &&
	        (f->dev!=dev || f->qid!=qid || f->date<mtime)){
		f->dev = dev;
		f->qid = qid;
		f->date = mtime;
		warn_S(Wdate, &genstr);
		return;
	}
	if(genc)
		free(genc);
	genc = Strtoc(&genstr);
	if((io=create(genc, 1, 0666L)) < 0)
		error_s(Ecreate, genc);
	dprint("%s: ", genc);
	if(statfd(io, 0, 0, 0, &length, &appendonly) > 0 && appendonly && length>0)
		error(Eappend);
	n = writeio(f);
	if(f->name.s[0]==0 || samename)
		state(f, addr.r.p1==0 && addr.r.p2==f->nrunes? Clean : Dirty);
	if(newfile)
		dprint("(new file) ");
	if(addr.r.p2>0 && Fchars(f, &c, addr.r.p2-1, addr.r.p2) && c!='\n')
		warn(Wnotnewline);
	closeio(n);
	if(f->name.s[0]==0 || samename){
		if(statfile(name, &dev, &qid, &mtime, 0, 0) > 0){
			f->dev = dev;
			f->qid = qid;
			f->date = mtime;
			checkqid(f);
		}
	}
}
예제 #4
0
파일: mesg.c 프로젝트: siebenmann/sam
void
snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok)
{
    Posn l;
    int i;

    if(!emptyok && p1==p2)
        return;
    Bdelete(buf, (Posn)0, buf->nrunes);
    /* Stage through genbuf to avoid compaction problems (vestigial) */
    for(l=p1; l<p2; l+=i) {
        i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l;
        Fchars(f, genbuf, l, l+i);
        Binsert(buf, tmprstr(genbuf, i), buf->nrunes);
    }
}
예제 #5
0
파일: mesg.c 프로젝트: siebenmann/sam
void
setgenstr(File *f, Posn p0, Posn p1)
{
    if(p0 != p1) {
        if(p1-p0 >= TBLOCKSIZE)
            error(Etoolong);
        Strinsure(&genstr, p1-p0);
        Fchars(f, genbuf, p0, p1);
        memmove(genstr.s, genbuf, RUNESIZE*(p1-p0));
        genstr.n = p1-p0;
    } else {
        if(snarfbuf->nrunes == 0)
            error(Eempty);
        if(snarfbuf->nrunes > TBLOCKSIZE)
            error(Etoolong);
        Bread(snarfbuf, genbuf, snarfbuf->nrunes, (Posn)0);
        Strinsure(&genstr, snarfbuf->nrunes);
        memmove(genstr.s, genbuf, RUNESIZE*snarfbuf->nrunes);
        genstr.n = snarfbuf->nrunes;
    }
}
예제 #6
0
파일: xec.c 프로젝트: deadpixi/sam
bool
s_cmd(File *f, Cmd *cp)
{
    int i, j, c, n;
    Posn p1, op, delta = 0;
    bool didsub = false;

    n = cp->num;
    op= -1;
    compile(cp->re);
    for(p1 = addr.r.p1; p1<=addr.r.p2 && execute(f, p1, addr.r.p2); ){
        if(sel.p[0].p1==sel.p[0].p2){   /* empty match? */
            if(sel.p[0].p1==op){
                p1++;
                continue;
            }
            p1 = sel.p[0].p2+1;
        }else
            p1 = sel.p[0].p2;
        op = sel.p[0].p2;
        if(--n>0)
            continue;
        Strzero(&genstr);
        for(i = 0; i<cp->ctext->n; i++)
            if((c = cp->ctext->s[i])=='\\' && i<cp->ctext->n-1){
                c = cp->ctext->s[++i];
                if('1'<=c && c<='9') {
                    j = c-'0';
                    if(sel.p[j].p2-sel.p[j].p1>BLOCKSIZE)
                        error(Elongtag);
                    Fchars(f, genbuf, sel.p[j].p1, sel.p[j].p2);
                    Strinsert(&genstr, tmprstr(genbuf, (sel.p[j].p2-sel.p[j].p1)), genstr.n);
                }else
                    Straddc(&genstr, c);
            }else if(c!='&')
                Straddc(&genstr, c);
            else{
                if(sel.p[0].p2-sel.p[0].p1>BLOCKSIZE)
                    error(Elongrhs);
                Fchars(f, genbuf, sel.p[0].p1, sel.p[0].p2);
                Strinsert(&genstr,
                    tmprstr(genbuf, (int)(sel.p[0].p2-sel.p[0].p1)),
                    genstr.n);
            }
        if(sel.p[0].p1!=sel.p[0].p2){
            Fdelete(f, sel.p[0].p1, sel.p[0].p2);
            delta-=sel.p[0].p2-sel.p[0].p1;
        }
        if(genstr.n){
            Finsert(f, &genstr, sel.p[0].p2);
            delta+=genstr.n;
        }
        didsub = true;
        if(!cp->flag)
            break;
    }
    if(!didsub && nest==0)
        error(Enosub);
    f->ndot.r.p1 = addr.r.p1, f->ndot.r.p2 = addr.r.p2+delta;
    return true;
}
예제 #7
0
파일: mesg.c 프로젝트: siebenmann/sam
int
inmesg(Tmesg type)
{
    Rune buf[1025];
    int i, m;
    short s;
    long l, l1;
    File *f;
    Posn p0, p1;
    Range r;
    String *str;
    char *c;
    Rune *rp;

    if(type > TMAX)
        panic("inmesg");

    journal(0, tname[type]);

    inp = indata;
    switch(type) {
    case -1:
        panic("rcv error");

    default:
        fprint(2, "unknown type %d\n", type);
        panic("rcv unknown");

    case Tversion:
        tversion = inshort();
        journaln(0, tversion);
        break;

    case Tstartcmdfile:
        l = invlong();		/* for 64-bit pointers */
        journaln(0, l);
        Strdupl(&genstr, samname);
        cmd = newfile();
        outTsv(Hbindname, cmd->tag, l);
        outTs(Hcurrent, cmd->tag);
        Fsetname(cmd, &genstr);
        cmd->rasp = emalloc(sizeof(List));
        cmd->state = Clean;
        if(cmdstr.n) {
            Finsert(cmd, &cmdstr, 0L);
            Strdelete(&cmdstr, 0L, (Posn)cmdstr.n);
        }
        Fupdate(cmd, FALSE, TRUE);
        outT0(Hunlock);
        break;

    case Tcheck:
        /* go through whichfile to check the tag */
        outTs(Hcheck, whichfile(inshort())->tag);
        break;

    case Trequest:
        f = whichfile(inshort());
        p0 = inlong();
        p1 = p0+inshort();
        journaln(0, p0);
        journaln(0, p1-p0);
        if(f->state == Unread)
            panic("Trequest: unread");
        if(p1>f->nrunes)
            p1 = f->nrunes;
        if(p0>f->nrunes) /* can happen e.g. scrolling during command */
            p0 = f->nrunes;
        if(p0 == p1) {
            i = 0;
            r.p1 = r.p2 = p0;
        } else {
            r = rdata(f->rasp, p0, p1-p0);
            i = r.p2-r.p1;
            if(Fchars(f, buf, r.p1, r.p2)!=i)
                panic("Trequest 2");
        }
        buf[i]=0;
        outTslS(Hdata, f->tag, r.p1, tmprstr(buf, i+1));
        break;

    case Torigin:
        s = inshort();
        l = inlong();
        l1 = inlong();
        journaln(0, l1);
        lookorigin(whichfile(s), l, l1);
        break;

    case Tstartfile:
        termlocked++;
        f = whichfile(inshort());
        if(!f->rasp)	/* this might be a duplicate message */
            f->rasp = emalloc(sizeof(List));
        current(f);
        outTsv(Hbindname, f->tag, invlong());	/* for 64-bit pointers */
        outTs(Hcurrent, f->tag);
        journaln(0, f->tag);
        if(f->state == Unread)
            load(f);
        else {
            if(f->nrunes>0) {
                rgrow(f->rasp, 0L, f->nrunes);
                outTsll(Hgrow, f->tag, 0L, f->nrunes);
            }
            outTs(Hcheck0, f->tag);
            moveto(f, f->dot.r);
        }
        break;

    case Tworkfile:
        i = inshort();
        f = whichfile(i);
        current(f);
        f->dot.r.p1 = inlong();
        f->dot.r.p2 = inlong();
        f->tdot = f->dot.r;
        journaln(0, i);
        journaln(0, f->dot.r.p1);
        journaln(0, f->dot.r.p2);
        break;

    case Ttype:
        f = whichfile(inshort());
        p0 = inlong();
        journaln(0, p0);
        journal(0, (char*)inp);
        str = tmpcstr((char*)inp);
        i = str->n;
        Finsert(f, str, p0);
        if(Fupdate(f, FALSE, FALSE))
            modnum++;
        if(f==cmd && p0==f->nrunes-i && i>0 && str->s[i-1]=='\n') {
            freetmpstr(str);
            termlocked++;
            termcommand();
        } else
            freetmpstr(str);
        f->dot.r.p1 = f->dot.r.p2 = p0+i; /* terminal knows this already */
        f->tdot = f->dot.r;
        break;

    case Tcut:
        f = whichfile(inshort());
        p0 = inlong();
        p1 = inlong();
        journaln(0, p0);
        journaln(0, p1);
        Fdelete(f, p0, p1);
        if(Fupdate(f, FALSE, FALSE))
            modnum++;
        f->dot.r.p1 = f->dot.r.p2 = p0;
        f->tdot = f->dot.r;   /* terminal knows the value of dot already */
        break;

    case Tpaste:
        f = whichfile(inshort());
        p0 = inlong();
        journaln(0, p0);
        for(l=0; l<snarfbuf->nrunes; l+=m) {
            m = snarfbuf->nrunes-l;
            if(m>BLOCKSIZE)
                m = BLOCKSIZE;
            Bread(snarfbuf, genbuf, m, l);
            Finsert(f, tmprstr(genbuf, m), p0);
        }
        if(Fupdate(f, FALSE, TRUE))
            modnum++;
        f->dot.r.p1 = p0;
        f->dot.r.p2 = p0+snarfbuf->nrunes;
        f->tdot.p1 = -1; /* force telldot to tell (arguably a BUG) */
        telldot(f);
        outTs(Hunlockfile, f->tag);
        break;

    case Tsnarf:
        i = inshort();
        p0 = inlong();
        p1 = inlong();
        snarf(whichfile(i), p0, p1, snarfbuf, 0);
        break;

    case Tstartnewfile:
        l = invlong();
        Strdupl(&genstr, empty);
        f = newfile();
        f->rasp = emalloc(sizeof(List));
        outTsv(Hbindname, f->tag, l);
        Fsetname(f, &genstr);
        outTs(Hcurrent, f->tag);
        current(f);
        load(f);
        break;

    case Twrite:
        termlocked++;
        i = inshort();
        journaln(0, i);
        f = whichfile(i);
        addr.r.p1 = 0;
        addr.r.p2 = f->nrunes;
        if(f->name.s[0] == 0)
            error(Enoname);
        Strduplstr(&genstr, &f->name);
        writef(f);
        break;

    case Tclose:
        termlocked++;
        i = inshort();
        journaln(0, i);
        f = whichfile(i);
        current(f);
        trytoclose(f);
        /* if trytoclose fails, will error out */
        delete(f);
        break;

    case Tlook:
        f = whichfile(inshort());
        termlocked++;
        p0 = inlong();
        p1 = inlong();
        journaln(0, p0);
        journaln(0, p1);
        setgenstr(f, p0, p1);
        for(l = 0; l<genstr.n; l++) {
            i = genstr.s[l];
            if(utfrune(".*+?(|)\\[]^$", i))
                Strinsert(&genstr, tmpcstr("\\"), l++);
        }
        Straddc(&genstr, '\0');
        nextmatch(f, &genstr, p1, 1);
        moveto(f, sel.p[0]);
        break;

    case Tsearch:
        termlocked++;
        if(curfile == 0)
            error(Enofile);
        if(lastpat.s[0] == 0)
            panic("Tsearch");
        nextmatch(curfile, &lastpat, curfile->dot.r.p2, 1);
        moveto(curfile, sel.p[0]);
        break;

    case Tsend:
        termlocked++;
        inshort();	/* ignored */
        p0 = inlong();
        p1 = inlong();
        setgenstr(cmd, p0, p1);
        Bdelete(snarfbuf, (Posn)0, snarfbuf->nrunes);
        Binsert(snarfbuf, &genstr, (Posn)0);
        outTl(Hsnarflen, genstr.n);
        if(genstr.s[genstr.n-1] != '\n')
            Straddc(&genstr, '\n');
        Finsert(cmd, &genstr, cmd->nrunes);
        Fupdate(cmd, FALSE, TRUE);
        cmd->dot.r.p1 = cmd->dot.r.p2 = cmd->nrunes;
        telldot(cmd);
        termcommand();
        break;

    case Tdclick:
        f = whichfile(inshort());
        p1 = inlong();
        doubleclick(f, p1);
        f->tdot.p1 = f->tdot.p2 = p1;
        telldot(f);
        outTs(Hunlockfile, f->tag);
        break;

    case Tstartsnarf:
        if (snarfbuf->nrunes <= 0) {	/* nothing to export */
            outTs(Hsetsnarf, 0);
            break;
        }
        c = 0;
        i = 0;
        m = snarfbuf->nrunes;
        if(m > 32000) {		/* tmprstr stores len in a short */
            m = 32000;
            dprint("?warning: snarf buffer truncated\n");
        }
        rp = malloc(m*sizeof(Rune));
        if(rp) {
            Bread(snarfbuf, rp, m, 0);
            c = Strtoc(tmprstr(rp, m));
            free(rp);
            i = strlen(c);
        }
        outTs(Hsetsnarf, i);
        if(c) {
            Write(1, c, i);
            free(c);
        } else
            dprint("snarf buffer too long\n");
        break;

    case Tsetsnarf:
        m = inshort();
        if(m > SNARFSIZE)
            error(Etoolong);
        c = malloc(m+1);
        if(c) {
            for(i=0; i<m; i++)
                c[i] = rcvchar();
            c[m] = 0;
            str = tmpcstr(c);
            free(c);
            Bdelete(snarfbuf, (Posn)0, snarfbuf->nrunes);
            Binsert(snarfbuf, str, (Posn)0);
            freetmpstr(str);
            outT0(Hunlock);
        }
        break;

    case Tack:
        waitack = 0;
        break;

    case Texit:
        exits(0);
    }
    return TRUE;
}