int s_cmd(File *f, Cmd *cp) { int i, j, c, n; Posn p1, op, didsub = 0, delta = 0; 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); bufread(&f->b, sel.p[j].p1, genbuf, sel.p[j].p2-sel.p[j].p1); 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); bufread(&f->b, sel.p[0].p1, genbuf, sel.p[0].p2-sel.p[0].p1); Strinsert(&genstr, tmprstr(genbuf, (int)(sel.p[0].p2-sel.p[0].p1)), genstr.n); } if(sel.p[0].p1!=sel.p[0].p2){ logdelete(f, sel.p[0].p1, sel.p[0].p2); delta-=sel.p[0].p2-sel.p[0].p1; } if(genstr.n){ loginsert(f, sel.p[0].p2, genstr.s, genstr.n); delta+=genstr.n; } didsub = 1; 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; }
int display(File *f) { Posn p1, p2; int np; char *c; p1 = addr.r.p1; p2 = addr.r.p2; if(p2 > f->b.nc){ fprint(2, "bad display addr p1=%ld p2=%ld f->b.nc=%d\n", p1, p2, f->b.nc); /*ZZZ should never happen, can remove */ p2 = f->b.nc; } while(p1 < p2){ np = p2-p1; if(np>BLOCKSIZE-1) np = BLOCKSIZE-1; bufread(&f->b, p1, genbuf, np); genbuf[np] = 0; c = Strtoc(tmprstr(genbuf, np+1)); if(downloaded) termwrite(c); else Write(1, c, strlen(c)); free(c); p1 += np; } f->dot = addr; return TRUE; }
void fileundelete(File *f, Buffer *delta, uint p0, uint p1) { Undo u; Rune *buf; uint i, n; /* undo a deletion by inserting */ u.type = Insert; u.mod = f->mod; u.seq = f->seq; u.p0 = p0; u.n = p1-p0; buf = fbufalloc(); for(i=p0; i<p1; i+=n){ n = p1 - i; if(n > RBUFSIZE) n = RBUFSIZE; bufread(&f->b, i, buf, n); bufinsert(delta, delta->nc, buf, n); } fbuffree(buf); bufinsert(delta, delta->nc, (Rune*)&u, Undosize); }
void acmeputsnarf(void) { int i, n; Fmt f; char *s; if(snarfbuf.nc==0) return; if(snarfbuf.nc > MAXSNARF) return; fmtstrinit(&f); for(i=0; i<snarfbuf.nc; i+=n){ n = snarfbuf.nc-i; if(n >= NSnarf) n = NSnarf; bufread(&snarfbuf, i, snarfrune, n); if(fmtprint(&f, "%.*S", n, snarfrune) < 0) break; } s = fmtstrflush(&f); if(s && s[0]) putsnarf(s); free(s); }
void textfill(Text *t) { Rune *rp; int i, n, m, nl; if(t->lastlinefull || t->nofill) return; if(t->ncache > 0) typecommit(t); rp = fbufalloc(); do{ n = t->file->nc-(t->org+t->nchars); if(n == 0) break; if(n > 2000) /* educated guess at reasonable amount */ n = 2000; bufread(t->file, t->org+t->nchars, rp, n); /* * it's expensive to frinsert more than we need, so * count newlines. */ nl = t->maxlines-t->nlines; m = 0; for(i=0; i<n; ){ if(rp[i++] == '\n'){ m++; if(m >= nl) break; } } frinsert(t, rp, rp+i, t->nchars); }while(t->lastlinefull == FALSE); fbuffree(rp); }
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; bufread(f, p, genbuf, n); c = Strtoc(tmprstr(genbuf, n)); m = strlen(c); if(Write(io, c, m) != m){ free(c); if(p > 0) p += n; break; } free(c); p += n; } return p-addr.r.p1; }
int main(int argc, char *argv[]) { int server; int n; messagedef_t request, response; header_t header; void *buf = NULL; if (argc != 3) { fprintf(stderr, "USAGE: application <server_ip> <port>\n"); exit(1); } /* open the TCP socket */ if ((server = open_connection(argv[1], atoi(argv[2]))) < 0) { fprintf(stderr, "ERROR; failed to create socket\n"); exit(1); } request.version = VERSION; request.command = GET_HDR; request.bufsize = 0; fprintf(stderr, "------------------------------\n"); print_request(&request); bufwrite(server, &request, sizeof(messagedef_t)); bufread(server, &response, sizeof(messagedef_t)); fprintf(stderr, "------------------------------\n"); print_response(&response); fprintf(stderr, "------------------------------\n"); if (response.command==GET_OK) { buf = malloc(response.bufsize); if ((n = bufread(server, buf, response.bufsize)) < response.bufsize) { fprintf(stderr, "problem reading enough bytes (%d)\n", n); } else { header.def = (headerdef_t *)buf; header.buf = (char *) buf+sizeof(headerdef_t); print_headerdef(header.def); } FREE(buf); } close(server); exit(0); }
int main(int argc, char *argv[]) { int server, offset; int n; messagedef_t request, response; event_t event; eventsel_t eventsel; void *buf = NULL; if (argc != 3) { fprintf(stderr, "USAGE: application <server_ip> <port>\n"); exit(1); } /* open the TCP socket */ if ((server = open_connection(argv[1], atoi(argv[2]))) < 0) { fprintf(stderr, "ERROR; failed to create socket\n"); exit(1); } request.version = VERSION; request.command = GET_EVT; request.bufsize = 0; // sizeof(eventsel_t); // eventsel.begevent = 0; // eventsel.endevent = 2; fprintf(stderr, "------------------------------\n"); print_request(&request); write(server, &request, sizeof(messagedef_t)); // write(server, &eventsel, sizeof(eventsel_t)); read(server, &response, sizeof(messagedef_t)); fprintf(stderr, "------------------------------\n"); print_response(&response); fprintf(stderr, "------------------------------\n"); if (response.command==GET_OK) { buf = malloc(response.bufsize); if ((n = bufread(server, buf, response.bufsize)) < response.bufsize) { fprintf(stderr, "problem reading enough bytes (%d)\n", n); } else { n = 0; offset = 0; while (offset<response.bufsize) { event.def = buf+offset; event.buf = buf+offset+sizeof(eventdef_t); fprintf(stderr, "\n"); print_eventdef(event.def); offset += sizeof(eventdef_t) + event.def->bufsize; n++; } } FREE(buf); } close(server); exit(0); }
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); }
int filereadc(File *f, uint q) { Rune r; if(q >= f->Buffer.nc) return -1; bufread(&f->Buffer, q, &r, 1); return r; }
Rune textreadc(Text *t, uint q) { Rune r; if(t->cq0<=q && q<t->cq0+t->ncache) r = t->cache[q-t->cq0]; else bufread(t->file, q, &r, 1); return r; }
/* return sequence number of pending redo */ uint fileredoseq(File *f) { Undo u; Buffer *delta; delta = &f->epsilon; if(delta->nc == 0) return 0; bufread(delta, delta->nc-Undosize, (Rune*)&u, Undosize); return u.seq; }
void mergeextend(File *f, uint p0) { uint mp0n; mp0n = merge.p0+merge.n; if(mp0n != p0){ bufread(&f->Buffer, mp0n, merge.buf+merge.nbuf, p0-mp0n); merge.nbuf += p0-mp0n; merge.n = p0-merge.p0; } }
void setgenstr(File *f, Posn p0, Posn p1) { if(p0 != p1){ if(p1-p0 >= TBLOCKSIZE) error(Etoolong); Strinsure(&genstr, p1-p0); bufread(&f->b, p0, genbuf, p1-p0); memmove(genstr.s, genbuf, RUNESIZE*(p1-p0)); genstr.n = p1-p0; }else{ if(snarfbuf.nc == 0) error(Eempty); if(snarfbuf.nc > TBLOCKSIZE) error(Etoolong); bufread(&snarfbuf, (Posn)0, genbuf, snarfbuf.nc); Strinsure(&genstr, snarfbuf.nc); memmove(genstr.s, genbuf, RUNESIZE*snarfbuf.nc); genstr.n = snarfbuf.nc; } }
int xfidruneread(Xfid *x, Text *t, uint q0, uint q1) { Fcall fc; Window *w; Rune *r, junk; char *b, *b1; uint q, boff; int i, rw, m, n, nr, nb; w = t->w; wincommit(w, t); r = fbufalloc(); b = fbufalloc(); b1 = fbufalloc(); n = 0; q = q0; boff = 0; while(q<q1 && n<x->fcall.count){ nr = q1-q; if(nr > BUFSIZE/UTFmax) nr = BUFSIZE/UTFmax; bufread(&t->file->b, q, r, nr); nb = snprint(b, BUFSIZE+1, "%.*S", nr, r); m = nb; if(boff+m > x->fcall.count){ i = x->fcall.count - boff; /* copy whole runes only */ m = 0; nr = 0; while(m < i){ rw = chartorune(&junk, b+m); if(m+rw > i) break; m += rw; nr++; } if(m == 0) break; } memmove(b1+n, b, m); n += m; boff += nb; q += nr; } fbuffree(r); fbuffree(b); fc.count = n; fc.data = b1; respond(x, &fc, nil); fbuffree(b1); return q-q0; }
long prevseq(Buffer *b) { Undo u; uint up; up = b->nc; if(up == 0) return 0; up -= Undosize; bufread(b, up, (Rune*)&u, Undosize); return u.seq; }
int readresponse(int serverfd, messagedef_t *responsedef) { /* N.B. this could happen at a later time */ /* 2. Read the response */ /* 2.1 Read response message */ int n=0; char* responsebuf = NULL; if ((n = bufread(serverfd, responsedef, sizeof(messagedef_t))) != sizeof(messagedef_t)) { fprintf(stderr, "packet size = %d, should be %d\n", n, sizeof(messagedef_t)); sig_handler(-1); } /* 2.2 Read response data if needed */ if (responsedef->bufsize>0) { responsebuf = malloc(responsedef->bufsize); if ((n = bufread(serverfd, responsebuf, responsedef->bufsize)) != responsedef->bufsize) { fprintf(stderr, "read size = %d, should be %d\n", n, responsedef->bufsize); sig_handler(-1); } /* ignore the response and free the memory */ free(responsebuf); } return 0; }
/* copy up-to size bytes into ptr and return the actual size copied */ static size_t codec_filebuf_callback(void *ptr, size_t size) { ssize_t copy_n = bufread(ci.audio_hid, size, ptr); /* Nothing requested OR nothing left */ if (copy_n <= 0) return 0; /* Update read and other position pointers */ codec_advance_buffer_counters(copy_n); /* Return the actual amount of data copied to the buffer */ return copy_n; }
/* called while row is locked */ void flushwarnings(void) { Warning *warn, *next; Window *w; Text *t; int owner, nr, q0, n; Rune *r; for(warn=warnings; warn; warn=next) { w = errorwin(warn->md, 'E'); t = &w->body; owner = w->owner; if(owner == 0) w->owner = 'E'; wincommit(w, t); /* * Most commands don't generate much output. For instance, * Edit ,>cat goes through /dev/cons and is already in blocks * because of the i/o system, but a few can. Edit ,p will * put the entire result into a single hunk. So it's worth doing * this in blocks (and putting the text in a buffer in the first * place), to avoid a big memory footprint. */ r = fbufalloc(); q0 = t->file->nc; for(n = 0; n < warn->buf.nc; n += nr){ nr = warn->buf.nc - n; if(nr > RBUFSIZE) nr = RBUFSIZE; bufread(&warn->buf, n, r, nr); textbsinsert(t, t->file->nc, r, nr, TRUE, &nr); } textshow(t, q0, t->file->nc, 1); free(r); winsettag(t->w); textscrdraw(t); w->owner = owner; w->dirty = FALSE; winunlock(w); bufclose(&warn->buf); next = warn->next; if(warn->md) fsysdelid(warn->md); free(warn); } warnings = nil; }
void newsel(Text* t) { int n, m, q, q0, q1; Rune *r; char *s; q0 = t->q0; q1 = t->q1; if(q0 == q1) return; latestselectionid++; free(selectionprocarg_context); if(t->file->name) selectionprocarg_context = runetobyte(t->file->name, t->file->nname); else selectionprocarg_context = strdup(getsrvname()); char* text = 0; int ntext = 0; r = fbufalloc(); s = fbufalloc(); for(q=q0; q<q1; q+=n) { n = q1 - q; if(n > BUFSIZE/UTFmax) n = BUFSIZE/UTFmax; bufread(&t->file->b, q, r, n); m = snprint(s, BUFSIZE+1, "%.*S", n, r); text = realloc(text, ntext + m); memcpy(text + ntext, s, m); ntext += m; } fbuffree(r); fbuffree(s); free(selectionprocarg_text); selectionprocarg_text = text; selectionprocarg_ntext = ntext; latestselectiontext = t; proccreate(selectionproc, nil, STACK); }
int inputc(void) { int n, nbuf; char buf[UTFmax]; Rune r; Again: nbuf = 0; if(cmdbufpos > cmdbuf.nc && cmdbuf.nc > 0){ cmdbufpos = 0; bufreset(&cmdbuf); } if(cmdbufpos < cmdbuf.nc && cmdbuf.nc > 0) bufread(&cmdbuf, cmdbufpos++, &r, 1); else if(downloaded){ while(termoutp == terminp){ cmdupdate(); if(patset) tellpat(); while(termlocked > 0){ outT0(Hunlock); termlocked--; } if(rcv() == 0) return -1; } r = *termoutp++; if(termoutp == terminp) terminp = termoutp = termline; }else{ do{ n = read(0, buf+nbuf, 1); if(n <= 0) return -1; nbuf += n; }while(!fullrune(buf, nbuf)); chartorune(&r, buf); } if(r == 0){ warn(Wnulls); goto Again; } return r; }
int codec_load_buf(int hid, struct codec_api *api) { int rc = bufread(hid, CODEC_SIZE, codecbuf); if (rc < 0) { logf("Codec: cannot read buf handle"); return CODEC_ERROR; } curr_handle = lc_open_from_mem(codecbuf, rc); if (curr_handle == NULL) { logf("Codec: load error"); return CODEC_ERROR; } return codec_load_ram(api); }
int codec_load_buf(unsigned int hid, struct codec_api *api) { int rc; void *handle; rc = bufread(hid, CODEC_SIZE, codecbuf); if (rc < 0) { logf("error loading codec"); return CODEC_ERROR; } handle = lc_open_from_mem(codecbuf, rc); if (handle == NULL) { logf("error loading codec"); return CODEC_ERROR; } api->discard_codec(); return codec_load_ram(handle, api); }
/* copy up-to size bytes into ptr and return the actual size copied */ static size_t codec_filebuf_callback(void *ptr, size_t size) { ssize_t copy_n; if (ci.stop_codec || !(audio_status() & AUDIO_STATUS_PLAY)) return 0; copy_n = bufread(get_audio_hid(), size, ptr); /* Nothing requested OR nothing left */ if (copy_n == 0) return 0; /* Update read and other position pointers */ codec_advance_buffer_counters(copy_n); /* Return the actual amount of data copied to the buffer */ return copy_n; } /* codec_filebuf_callback */
void snarf(File *f, Posn p1, Posn p2, Buffer *buf, int emptyok) { Posn l; int i; if(!emptyok && p1==p2) return; bufreset(buf); /* Stage through genbuf to avoid compaction problems (vestigial) */ if(p2 > f->b.nc){ fprint(2, "bad snarf addr p1=%ld p2=%ld f->b.nc=%d\n", p1, p2, f->b.nc); /*ZZZ should never happen, can remove */ p2 = f->b.nc; } for(l=p1; l<p2; l+=i){ i = p2-l>BLOCKSIZE? BLOCKSIZE : p2-l; bufread(&f->b, l, genbuf, i); bufinsert(buf, buf->nc, tmprstr(genbuf, i)->s, i); } }
void textsetorigin(Text *t, uint org, int exact) { int i, a, fixup; Rune *r; uint n; if(org>0 && !exact){ /* org is an estimate of the char posn; find a newline */ /* don't try harder than 256 chars */ for(i=0; i<256 && org<t->file->nc; i++){ if(textreadc(t, org) == '\n'){ org++; break; } org++; } } a = org-t->org; fixup = 0; if(a>=0 && a<t->nchars){ frdelete(t, 0, a); fixup = 1; /* frdelete can leave end of last line in wrong selection mode; it doesn't know what follows */ } else if(a<0 && -a<t->nchars){ n = t->org - org; r = runemalloc(n); bufread(t->file, org, r, n); frinsert(t, r, r+n, 0); free(r); }else frdelete(t, 0, t->nchars); t->org = org; textfill(t); textscrdraw(t); textsetselect(t, t->q0, t->q1); if(fixup && t->p1 > t->p0) frdrawsel(t, frptofchar(t, t->p1-1), t->p1-1, t->p1, 1); }
void putsnarf(void) { int fd, i, n; if(snarffd<0 || snarfbuf.nc==0) return; if(snarfbuf.nc > MAXSNARF) return; fd = open("/dev/snarf", OWRITE); if(fd < 0) return; for(i=0; i<snarfbuf.nc; i+=n){ n = snarfbuf.nc-i; if(n >= NSnarf) n = NSnarf; bufread(&snarfbuf, i, snarfrune, n); if(fprint(fd, "%.*S", n, snarfrune) < 0) break; } close(fd); }
Runestr dirname(Text *t, Rune *r, int n) { Rune *b, c; uint m, nt; int slash; Runestr tmp; b = nil; if(t==nil || t->w==nil) goto Rescue; nt = t->w->tag.file->b.nc; if(nt == 0) goto Rescue; if(n>=1 && r[0]=='/') goto Rescue; b = runemalloc(nt+n+1); bufread(&t->w->tag.file->b, 0, b, nt); slash = -1; for(m=0; m<nt; m++){ c = b[m]; if(c == '/') slash = m; if(c==' ' || c=='\t') break; } if(slash < 0) goto Rescue; runemove(b+slash+1, r, n); free(r); return cleanrname(runestr(b, slash+1+n)); Rescue: free(b); tmp = runestr(r, n); if(r) return cleanrname(tmp); return tmp; }
size_t fread(void *dest, size_t size, size_t count, FILE *stream) { size_t bytes = size*count; if (0 == bytes) return 0; // Must not read from a stream used for writing without flushing first. if (stream->state & STREAM_WRITE) { errno = -1; // need a better error code here stream->state |= STREAM_ERR; return 0; } stream->state |= STREAM_READ; int total = 0; if (stream->state & STREAM_UNGET) { *(unsigned char*)dest = stream->unget; dest++; stream->state &= ~STREAM_UNGET; ++total; if (0 == --bytes) return total; } int ret = 0; if (stream->buf_size > 0) { ret = bufread(stream, dest, bytes); } else { fflush(0); ret = read(stream->id, dest, bytes); } if (ret < 0) { errno = -ret; stream->state |= STREAM_ERR; return 0; } else { total += ret; } if (ret < bytes) { stream->state |= STREAM_EOF; } return total / size; }
void Port::stportread(Fn_2<void,char *,int> *fn,int len) { // mutex_lock(io_mutex); read=fn; /* Delete data which is no longer needed */ old+=len; taken=0; if(old) { if(nnew!=old) memmove(buf,buf+old,nnew-old); nnew-=old; old=0; /* If we have data and we have taken data on last read, restart the port (serv() will cause another read() call to be made to see if the remaining data can be taken). */ if(nnew && len) bufread(); } // mutex_unlock(io_mutex); }