void xfidindexread(Xfid *x) { Fcall fc; int i, j, m, n, nmax, isbuf, cnt, off; Window *w; char *b; Rune *r; Column *c; qlock(&row.lk); nmax = 0; for(j=0; j<row.ncol; j++){ c = row.col[j]; for(i=0; i<c->nw; i++){ w = c->w[i]; nmax += Ctlsize + w->tag.file->b.nc*UTFmax + 1; } } nmax++; isbuf = (nmax<=RBUFSIZE); if(isbuf) b = (char*)x->buf; else b = emalloc(nmax); r = fbufalloc(); n = 0; for(j=0; j<row.ncol; j++){ c = row.col[j]; for(i=0; i<c->nw; i++){ w = c->w[i]; /* only show the currently active window of a set */ if(w->body.file->curtext != &w->body) continue; winctlprint(w, b+n, 0); n += Ctlsize; m = min(RBUFSIZE, w->tag.file->b.nc); bufread(&w->tag.file->b, 0, r, m); m = n + snprint(b+n, nmax-n-1, "%.*S", m, r); while(n<m && b[n]!='\n') n++; b[n++] = '\n'; } } qunlock(&row.lk); off = x->fcall.offset; cnt = x->fcall.count; if(off > n) off = n; if(off+cnt > n) cnt = n-off; fc.count = cnt; memmove(r, b+off, cnt); fc.data = (char*)r; if(!isbuf) free(b); respond(x, &fc, nil); fbuffree(r); }
void xfidread(Xfid *x) { Fcall fc; int n, q; uint off; char *b; char buf[256]; Window *w; q = FILE(x->f->qid); w = x->f->w; if(w == nil){ fc.count = 0; switch(q){ case Qcons: case Qlabel: break; case Qindex: xfidindexread(x); return; default: warning(nil, "unknown qid %d\n", q); break; } respond(x, &fc, nil); return; } winlock(w, 'F'); if(w->col == nil){ winunlock(w); respond(x, &fc, Edel); return; } off = x->fcall.offset; switch(q){ case QWaddr: textcommit(&w->body, TRUE); clampaddr(w); sprint(buf, "%11d %11d ", w->addr.q0, w->addr.q1); goto Readbuf; case QWbody: xfidutfread(x, &w->body, w->body.file->b.nc, QWbody); break; case QWctl: b = winctlprint(w, buf, 1); goto Readb; Readbuf: b = buf; Readb: n = strlen(b); if(off > n) off = n; if(off+x->fcall.count > n) x->fcall.count = n-off; fc.count = x->fcall.count; fc.data = b+off; respond(x, &fc, nil); if(b != buf) free(b); break; case QWevent: xfideventread(x, w); break; case QWdata: /* 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->body.file->b.nc); 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; case QWrdsel: seek(w->rdselfd, off, 0); n = x->fcall.count; if(n > BUFSIZE) n = BUFSIZE; b = fbufalloc(); n = read(w->rdselfd, b, n); if(n < 0){ respond(x, &fc, "I/O error in temp file"); break; } fc.count = n; fc.data = b; respond(x, &fc, nil); fbuffree(b); break; default: sprint(buf, "unknown qid %d in read", q); respond(x, &fc, nil); } winunlock(w); }
void rowdump(Row *row, char *file) { int i, j, fd, m, n, dumped; uint q0, q1; Biobuf *b; char *buf, *a, *fontname; Rune *r; Column *c; Window *w, *w1; Text *t; if(row->ncol == 0) return; buf = fbufalloc(); if(file == nil){ if(home == nil){ warning(nil, "can't find file for dump: $home not defined\n"); goto Rescue; } sprint(buf, "%s/acme.dump", home); file = buf; } fd = create(file, OWRITE, 0600); if(fd < 0){ warning(nil, "can't open %s: %r\n", file); goto Rescue; } b = emalloc(sizeof(Biobuf)); Binit(b, fd, OWRITE); r = fbufalloc(); Bprint(b, "%s\n", wdir); Bprint(b, "%s\n", fontnames[0]); Bprint(b, "%s\n", fontnames[1]); for(i=0; i<row->ncol; i++){ c = row->col[i]; Bprint(b, "%11d", 100*(c->r.min.x-row->r.min.x)/Dx(row->r)); if(i == row->ncol-1) Bputc(b, '\n'); else Bputc(b, ' '); } for(i=0; i<row->ncol; i++){ c = row->col[i]; for(j=0; j<c->nw; j++) c->w[j]->body.file->dumpid = 0; } for(i=0; i<row->ncol; i++){ c = row->col[i]; for(j=0; j<c->nw; j++){ w = c->w[j]; wincommit(w, &w->tag); t = &w->body; /* windows owned by others get special treatment */ if(w->nopen[QWevent] > 0) if(w->dumpstr == nil) continue; /* zeroxes of external windows are tossed */ if(t->file->ntext > 1) for(n=0; n<t->file->ntext; n++){ w1 = t->file->text[n]->w; if(w == w1) continue; if(w1->nopen[QWevent]) goto Continue2; } fontname = ""; if(t->reffont->f != font) fontname = t->reffont->f->name; if(t->file->nname) a = runetobyte(t->file->name, t->file->nname); else a = emalloc(1); if(t->file->dumpid){ dumped = FALSE; Bprint(b, "x%11d %11d %11d %11d %11d %s\n", i, t->file->dumpid, w->body.q0, w->body.q1, 100*(w->r.min.y-c->r.min.y)/Dy(c->r), fontname); }else if(w->dumpstr){ dumped = FALSE; Bprint(b, "e%11d %11d %11d %11d %11d %s\n", i, t->file->dumpid, 0, 0, 100*(w->r.min.y-c->r.min.y)/Dy(c->r), fontname); }else if((w->dirty==FALSE && access(a, 0)==0) || w->isdir){ dumped = FALSE; t->file->dumpid = w->id; Bprint(b, "f%11d %11d %11d %11d %11d %s\n", i, w->id, w->body.q0, w->body.q1, 100*(w->r.min.y-c->r.min.y)/Dy(c->r), fontname); }else{ dumped = TRUE; t->file->dumpid = w->id; Bprint(b, "F%11d %11d %11d %11d %11d %11d %s\n", i, j, w->body.q0, w->body.q1, 100*(w->r.min.y-c->r.min.y)/Dy(c->r), w->body.file->nc, fontname); } free(a); winctlprint(w, buf, 0); Bwrite(b, buf, strlen(buf)); m = min(RBUFSIZE, w->tag.file->nc); bufread(w->tag.file, 0, r, m); n = 0; while(n<m && r[n]!='\n') n++; r[n++] = '\n'; Bprint(b, "%.*S", n, r); if(dumped){ q0 = 0; q1 = t->file->nc; while(q0 < q1){ n = q1 - q0; if(n > BUFSIZE/UTFmax) n = BUFSIZE/UTFmax; bufread(t->file, q0, r, n); Bprint(b, "%.*S", n, r); q0 += n; } } if(w->dumpstr){ if(w->dumpdir) Bprint(b, "%s\n%s\n", w->dumpdir, w->dumpstr); else Bprint(b, "\n%s\n", w->dumpstr); } Continue2:; } } Bterm(b); close(fd); free(b); fbuffree(r); Rescue: fbuffree(buf); }