mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-24 11:41:58 +00:00
missing programs
This commit is contained in:
parent
34ca7ee3bf
commit
6e2cec77b2
2 changed files with 746 additions and 0 deletions
90
src/cmd/fortune.c
Normal file
90
src/cmd/fortune.c
Normal file
|
@ -0,0 +1,90 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
|
||||
#define index findex
|
||||
char choice[2048];
|
||||
char index[] = "/sys/games/lib/fortunes.index";
|
||||
char fortunes[] = "/sys/games/lib/fortunes";
|
||||
|
||||
#define lrand rand
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
long offs;
|
||||
uchar off[4];
|
||||
int ix, nix;
|
||||
int newindex, oldindex;
|
||||
char *p;
|
||||
Dir *fbuf, *ixbuf;
|
||||
Biobuf *f, g;
|
||||
|
||||
newindex = 0;
|
||||
oldindex = 0;
|
||||
ix = offs = 0;
|
||||
if((f=Bopen(argc>1?argv[1]:fortunes, OREAD)) == 0){
|
||||
print("Misfortune!\n");
|
||||
exits("misfortune");
|
||||
}
|
||||
ixbuf = nil;
|
||||
if(argc == 1){
|
||||
ix = open(index, OREAD);
|
||||
if(ix>=0){
|
||||
oldindex = 1;
|
||||
ixbuf = dirfstat(ix);
|
||||
fbuf = dirfstat(Bfildes(f));
|
||||
if(ixbuf == nil || fbuf == nil){
|
||||
print("Misfortune?\n");
|
||||
exits("misfortune");
|
||||
}
|
||||
if(fbuf->mtime > ixbuf->mtime){
|
||||
nix = create(index, OWRITE, 0666);
|
||||
if(nix >= 0){
|
||||
close(ix);
|
||||
ix = nix;
|
||||
newindex = 1;
|
||||
oldindex = 0;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
ix = create(index, OWRITE, 0666);
|
||||
if(ix >= 0)
|
||||
newindex = 1;
|
||||
}
|
||||
}
|
||||
if(oldindex){
|
||||
seek(ix, lrand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0);
|
||||
read(ix, off, sizeof(off));
|
||||
Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0);
|
||||
p = Brdline(f, '\n');
|
||||
if(p){
|
||||
p[Blinelen(f)-1] = 0;
|
||||
strcpy(choice, p);
|
||||
}else
|
||||
strcpy(choice, "Misfortune!");
|
||||
}else{
|
||||
Binit(&g, ix, 1);
|
||||
srand(getpid());
|
||||
for(i=1;;i++){
|
||||
if(newindex)
|
||||
offs = Boffset(f);
|
||||
p = Brdline(f, '\n');
|
||||
if(p == 0)
|
||||
break;
|
||||
p[Blinelen(f)-1] = 0;
|
||||
if(newindex){
|
||||
off[0] = offs;
|
||||
off[1] = offs>>8;
|
||||
off[2] = offs>>16;
|
||||
off[3] = offs>>24;
|
||||
Bwrite(&g, off, sizeof(off));
|
||||
}
|
||||
if(lrand()%i==0)
|
||||
strcpy(choice, p);
|
||||
}
|
||||
}
|
||||
print("%s\n", choice);
|
||||
exits(0);
|
||||
}
|
656
src/cmd/win.c
Normal file
656
src/cmd/win.c
Normal file
|
@ -0,0 +1,656 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <thread.h>
|
||||
#include <fcall.h>
|
||||
#include <fs.h>
|
||||
|
||||
#define EVENTSIZE 256
|
||||
#define STACK 32768
|
||||
|
||||
typedef struct Event Event;
|
||||
typedef struct Q Q;
|
||||
|
||||
struct Event
|
||||
{
|
||||
int c1;
|
||||
int c2;
|
||||
int q0;
|
||||
int q1;
|
||||
int flag;
|
||||
int nb;
|
||||
int nr;
|
||||
char b[EVENTSIZE*UTFmax+1];
|
||||
Rune r[EVENTSIZE+1];
|
||||
};
|
||||
|
||||
Event blank = {
|
||||
'M',
|
||||
'X',
|
||||
0, 0, 0, 1, 1,
|
||||
{ ' ', 0 },
|
||||
{ ' ', 0 },
|
||||
};
|
||||
|
||||
struct Q
|
||||
{
|
||||
QLock lk;
|
||||
int p;
|
||||
int k;
|
||||
};
|
||||
|
||||
Q q;
|
||||
|
||||
int eventfd;
|
||||
int addrfd;
|
||||
int datafd;
|
||||
int ctlfd;
|
||||
int bodyfd;
|
||||
|
||||
char *typing;
|
||||
int ntypeb;
|
||||
int ntyper;
|
||||
int ntypebreak;
|
||||
int debug;
|
||||
|
||||
char **prog;
|
||||
int p[2];
|
||||
Channel *cpid;
|
||||
int pid = -1;
|
||||
|
||||
void error(char*);
|
||||
void stdinproc(void*);
|
||||
void stdoutproc(void*);
|
||||
void type(Event*, int, int, int);
|
||||
void sende(Event*, int, int, int, int, int);
|
||||
char *onestring(int, char**);
|
||||
int delete(Event*);
|
||||
void deltype(uint, uint);
|
||||
void runproc(void*);
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: win cmd args...\n");
|
||||
threadexitsall("usage");
|
||||
}
|
||||
|
||||
int
|
||||
nopipes(void *v, char *msg)
|
||||
{
|
||||
USED(v);
|
||||
if(strcmp(msg, "sys: write on closed pipe") == 0)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
threadmain(int argc, char **argv)
|
||||
{
|
||||
int fd, id;
|
||||
char buf[256];
|
||||
char buf1[128];
|
||||
char *name;
|
||||
Fsys *fs;
|
||||
|
||||
ARGBEGIN{
|
||||
case 'd':
|
||||
debug = 1;
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}ARGEND
|
||||
|
||||
prog = argv;
|
||||
|
||||
if(argc > 0)
|
||||
name = argv[0];
|
||||
else
|
||||
name = "gnot";
|
||||
|
||||
threadnotify(nopipes, 1);
|
||||
if((fs = nsmount("acme", "")) < 0)
|
||||
sysfatal("nsmount acme: %r");
|
||||
ctlfd = fsopenfd(fs, "new/ctl", ORDWR|OCEXEC);
|
||||
if(ctlfd < 0 || read(ctlfd, buf, 12) != 12)
|
||||
sysfatal("ctl: %r");
|
||||
id = atoi(buf);
|
||||
sprint(buf, "%d/tag", id);
|
||||
fd = fsopenfd(fs, buf, OWRITE|OCEXEC);
|
||||
write(fd, " Send Delete", 12);
|
||||
close(fd);
|
||||
sprint(buf, "%d/event", id);
|
||||
eventfd = fsopenfd(fs, buf, ORDWR|OCEXEC);
|
||||
sprint(buf, "%d/addr", id);
|
||||
addrfd = fsopenfd(fs, buf, ORDWR|OCEXEC);
|
||||
sprint(buf, "%d/data", id);
|
||||
datafd = fsopenfd(fs, buf, ORDWR|OCEXEC);
|
||||
sprint(buf, "%d/body", id);
|
||||
bodyfd = fsopenfd(fs, buf, ORDWR|OCEXEC);
|
||||
if(eventfd<0 || addrfd<0 || datafd<0 || bodyfd<0)
|
||||
sysfatal("data files: %r");
|
||||
fsunmount(fs);
|
||||
|
||||
if(pipe(p) < 0)
|
||||
sysfatal("pipe: %r");
|
||||
|
||||
cpid = chancreate(sizeof(ulong), 1);
|
||||
threadcreate(runproc, nil, STACK);
|
||||
pid = recvul(cpid);
|
||||
if(pid == -1)
|
||||
sysfatal("exec failed");
|
||||
|
||||
getwd(buf1, sizeof buf1);
|
||||
sprint(buf, "name %s/-%s\n0\n", buf1, name);
|
||||
write(ctlfd, buf, strlen(buf));
|
||||
sprint(buf, "dumpdir %s/\n", buf1);
|
||||
write(ctlfd, buf, strlen(buf));
|
||||
sprint(buf, "dump %s\n", onestring(argc, argv));
|
||||
write(ctlfd, buf, strlen(buf));
|
||||
|
||||
// proccreate(stdoutproc, nil, STACK);
|
||||
stdinproc(nil);
|
||||
}
|
||||
|
||||
char *shell[] = { "rc", "-i", 0 };
|
||||
void
|
||||
runproc(void *v)
|
||||
{
|
||||
int fd[3];
|
||||
char *sh;
|
||||
|
||||
USED(v);
|
||||
|
||||
fd[0] = p[1];
|
||||
fd[1] = bodyfd;
|
||||
fd[2] = bodyfd;
|
||||
// fd[1] = p[1];
|
||||
// fd[2] = p[1];
|
||||
|
||||
if(prog[0] == nil){
|
||||
prog = shell;
|
||||
if((sh = getenv("SHELL")) != nil)
|
||||
shell[0] = sh;
|
||||
}
|
||||
threadexec(cpid, fd, prog[0], prog);
|
||||
threadexits(nil);
|
||||
}
|
||||
|
||||
void
|
||||
error(char *s)
|
||||
{
|
||||
if(s)
|
||||
fprint(2, "win: %s: %r\n", s);
|
||||
else
|
||||
s = "kill";
|
||||
if(pid != -1)
|
||||
postnote(PNGROUP, pid, "hangup");
|
||||
threadexitsall(s);
|
||||
}
|
||||
|
||||
char*
|
||||
onestring(int argc, char **argv)
|
||||
{
|
||||
char *p;
|
||||
int i, n;
|
||||
static char buf[1024];
|
||||
|
||||
if(argc == 0)
|
||||
return "";
|
||||
p = buf;
|
||||
for(i=0; i<argc; i++){
|
||||
n = strlen(argv[i]);
|
||||
if(p+n+1 >= buf+sizeof buf)
|
||||
break;
|
||||
memmove(p, argv[i], n);
|
||||
p += n;
|
||||
*p++ = ' ';
|
||||
}
|
||||
p[-1] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
getec(int efd)
|
||||
{
|
||||
static char buf[8192];
|
||||
static char *bufp;
|
||||
static int nbuf;
|
||||
|
||||
if(nbuf == 0){
|
||||
nbuf = read(efd, buf, sizeof buf);
|
||||
if(nbuf <= 0)
|
||||
error(nil);
|
||||
bufp = buf;
|
||||
}
|
||||
--nbuf;
|
||||
return *bufp++;
|
||||
}
|
||||
|
||||
int
|
||||
geten(int efd)
|
||||
{
|
||||
int n, c;
|
||||
|
||||
n = 0;
|
||||
while('0'<=(c=getec(efd)) && c<='9')
|
||||
n = n*10+(c-'0');
|
||||
if(c != ' ')
|
||||
error("event number syntax");
|
||||
return n;
|
||||
}
|
||||
|
||||
int
|
||||
geter(int efd, char *buf, int *nb)
|
||||
{
|
||||
Rune r;
|
||||
int n;
|
||||
|
||||
r = getec(efd);
|
||||
buf[0] = r;
|
||||
n = 1;
|
||||
if(r < Runeself)
|
||||
goto Return;
|
||||
while(!fullrune(buf, n))
|
||||
buf[n++] = getec(efd);
|
||||
chartorune(&r, buf);
|
||||
Return:
|
||||
*nb = n;
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
gete(int efd, Event *e)
|
||||
{
|
||||
int i, nb;
|
||||
|
||||
e->c1 = getec(efd);
|
||||
e->c2 = getec(efd);
|
||||
e->q0 = geten(efd);
|
||||
e->q1 = geten(efd);
|
||||
e->flag = geten(efd);
|
||||
e->nr = geten(efd);
|
||||
if(e->nr > EVENTSIZE)
|
||||
error("event string too long");
|
||||
e->nb = 0;
|
||||
for(i=0; i<e->nr; i++){
|
||||
e->r[i] = geter(efd, e->b+e->nb, &nb);
|
||||
e->nb += nb;
|
||||
}
|
||||
e->r[e->nr] = 0;
|
||||
e->b[e->nb] = 0;
|
||||
if(getec(efd) != '\n')
|
||||
error("event syntax 2");
|
||||
}
|
||||
|
||||
int
|
||||
nrunes(char *s, int nb)
|
||||
{
|
||||
int i, n;
|
||||
Rune r;
|
||||
|
||||
n = 0;
|
||||
for(i=0; i<nb; n++)
|
||||
i += chartorune(&r, s+i);
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
stdinproc(void *v)
|
||||
{
|
||||
int cfd = ctlfd;
|
||||
int efd = eventfd;
|
||||
int dfd = datafd;
|
||||
int afd = addrfd;
|
||||
int fd0 = p[0];
|
||||
Event e, e2, e3, e4;
|
||||
|
||||
USED(v);
|
||||
|
||||
for(;;){
|
||||
if(debug)
|
||||
fprint(2, "typing[%d,%d)\n", q.p, q.p+ntyper);
|
||||
gete(efd, &e);
|
||||
if(debug)
|
||||
fprint(2, "msg %c%c q[%d,%d)... ", e.c1, e.c2, e.q0, e.q1);
|
||||
qlock(&q.lk);
|
||||
switch(e.c1){
|
||||
default:
|
||||
Unknown:
|
||||
print("unknown message %c%c\n", e.c1, e.c2);
|
||||
break;
|
||||
|
||||
case 'E': /* write to body; can't affect us */
|
||||
if(debug)
|
||||
fprint(2, "shift typing %d... ", e.q1-e.q0);
|
||||
q.p += e.q1-e.q0;
|
||||
break;
|
||||
|
||||
case 'F': /* generated by our actions; ignore */
|
||||
break;
|
||||
|
||||
case 'K':
|
||||
case 'M':
|
||||
switch(e.c2){
|
||||
case 'I':
|
||||
if(e.q0 < q.p){
|
||||
if(debug)
|
||||
fprint(2, "shift typing %d... ", e.q1-e.q0);
|
||||
q.p += e.q1-e.q0;
|
||||
}
|
||||
else if(e.q0 <= q.p+ntyper){
|
||||
if(debug)
|
||||
fprint(2, "type... ");
|
||||
type(&e, fd0, afd, dfd);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'D':
|
||||
q.p -= delete(&e);
|
||||
break;
|
||||
|
||||
case 'x':
|
||||
case 'X':
|
||||
if(e.flag & 2)
|
||||
gete(efd, &e2);
|
||||
if(e.flag & 8){
|
||||
gete(efd, &e3);
|
||||
gete(efd, &e4);
|
||||
}
|
||||
if(e.flag&1 || (e.c2=='x' && e.nr==0 && e2.nr==0)){
|
||||
/* send it straight back */
|
||||
fprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1);
|
||||
break;
|
||||
}
|
||||
if(e.q0==e.q1 && (e.flag&2)){
|
||||
e2.flag = e.flag;
|
||||
e = e2;
|
||||
}
|
||||
if(e.flag & 8){
|
||||
if(e.q1 != e.q0){
|
||||
sende(&e, fd0, cfd, afd, dfd, 0);
|
||||
sende(&blank, fd0, cfd, afd, dfd, 0);
|
||||
}
|
||||
sende(&e3, fd0, cfd, afd, dfd, 1);
|
||||
}else if(e.q1 != e.q0)
|
||||
sende(&e, fd0, cfd, afd, dfd, 1);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'L':
|
||||
/* just send it back */
|
||||
if(e.flag & 2)
|
||||
gete(efd, &e2);
|
||||
fprint(efd, "%c%c%d %d\n", e.c1, e.c2, e.q0, e.q1);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
case 'i':
|
||||
break;
|
||||
|
||||
default:
|
||||
goto Unknown;
|
||||
}
|
||||
}
|
||||
qunlock(&q.lk);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stdoutproc(void *v)
|
||||
{
|
||||
int fd1 = p[0];
|
||||
int afd = addrfd;
|
||||
int dfd = datafd;
|
||||
int n, m, w, npart;
|
||||
char *buf, *s, *t;
|
||||
Rune r;
|
||||
char x[16], hold[UTFmax];
|
||||
|
||||
USED(v);
|
||||
threadnotify(nopipes, 1);
|
||||
buf = malloc(8192+UTFmax+1);
|
||||
npart = 0;
|
||||
for(;;){
|
||||
n = read(fd1, buf+npart, 8192);
|
||||
if(n < 0)
|
||||
error(nil);
|
||||
if(n == 0)
|
||||
continue;
|
||||
|
||||
/* squash NULs */
|
||||
s = memchr(buf+npart, 0, n);
|
||||
if(s){
|
||||
for(t=s; s<buf+npart+n; s++)
|
||||
if(*t = *s) /* assign = */
|
||||
t++;
|
||||
n = t-(buf+npart);
|
||||
}
|
||||
|
||||
n += npart;
|
||||
|
||||
/* hold on to final partial rune */
|
||||
npart = 0;
|
||||
while(n>0 && (buf[n-1]&0xC0)){
|
||||
--n;
|
||||
npart++;
|
||||
if((buf[n]&0xC0)!=0x80){
|
||||
if(fullrune(buf+n, npart)){
|
||||
w = chartorune(&r, buf+n);
|
||||
n += w;
|
||||
npart -= w;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(n > 0){
|
||||
memmove(hold, buf+n, npart);
|
||||
buf[n] = 0;
|
||||
qlock(&q.lk);
|
||||
m = sprint(x, "#%d", q.p);
|
||||
if(write(afd, x, m) != m)
|
||||
error("stdout writing address");
|
||||
if(write(dfd, buf, n) != n)
|
||||
error("stdout writing body");
|
||||
q.p += nrunes(buf, n);
|
||||
qunlock(&q.lk);
|
||||
memmove(buf, hold, npart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
delete(Event *e)
|
||||
{
|
||||
uint q0, q1;
|
||||
int deltap;
|
||||
|
||||
q0 = e->q0;
|
||||
q1 = e->q1;
|
||||
if(q1 <= q.p)
|
||||
return e->q1-e->q0;
|
||||
if(q0 >= q.p+ntyper)
|
||||
return 0;
|
||||
deltap = 0;
|
||||
if(q0 < q.p){
|
||||
deltap = q.p-q0;
|
||||
q0 = 0;
|
||||
}else
|
||||
q0 -= q.p;
|
||||
if(q1 > q.p+ntyper)
|
||||
q1 = ntyper;
|
||||
else
|
||||
q1 -= q.p;
|
||||
deltype(q0, q1);
|
||||
return deltap;
|
||||
}
|
||||
|
||||
void
|
||||
addtype(int c, uint p0, char *b, int nb, int nr)
|
||||
{
|
||||
int i, w;
|
||||
Rune r;
|
||||
uint p;
|
||||
char *b0;
|
||||
|
||||
for(i=0; i<nb; i+=w){
|
||||
w = chartorune(&r, b+i);
|
||||
if((r==0x7F||r==3) && c=='K'){
|
||||
postnote(PNGROUP, pid, "interrupt");
|
||||
/* toss all typing */
|
||||
q.p += ntyper+nr;
|
||||
ntypebreak = 0;
|
||||
ntypeb = 0;
|
||||
ntyper = 0;
|
||||
/* buglet: more than one delete ignored */
|
||||
return;
|
||||
}
|
||||
if(r=='\n' || r==0x04)
|
||||
ntypebreak++;
|
||||
}
|
||||
typing = realloc(typing, ntypeb+nb);
|
||||
if(typing == nil)
|
||||
error("realloc");
|
||||
if(p0 == ntyper)
|
||||
memmove(typing+ntypeb, b, nb);
|
||||
else{
|
||||
b0 = typing;
|
||||
for(p=0; p<p0 && b0<typing+ntypeb; p++){
|
||||
w = chartorune(&r, b0+i);
|
||||
b0 += w;
|
||||
}
|
||||
if(p != p0)
|
||||
error("typing: findrune");
|
||||
memmove(b0+nb, b0, (typing+ntypeb)-b0);
|
||||
memmove(b0, b, nb);
|
||||
}
|
||||
ntypeb += nb;
|
||||
ntyper += nr;
|
||||
}
|
||||
|
||||
void
|
||||
sendtype(int fd0)
|
||||
{
|
||||
int i, n, nr;
|
||||
|
||||
while(ntypebreak){
|
||||
for(i=0; i<ntypeb; i++)
|
||||
if(typing[i]=='\n' || typing[i]==0x04){
|
||||
n = i + (typing[i] == '\n');
|
||||
i++;
|
||||
if(write(fd0, typing, n) != n)
|
||||
error("sending to program");
|
||||
nr = nrunes(typing, i);
|
||||
q.p += nr;
|
||||
ntyper -= nr;
|
||||
ntypeb -= i;
|
||||
memmove(typing, typing+i, ntypeb);
|
||||
ntypebreak--;
|
||||
goto cont2;
|
||||
}
|
||||
print("no breakchar\n");
|
||||
ntypebreak = 0;
|
||||
cont2:
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
deltype(uint p0, uint p1)
|
||||
{
|
||||
int w;
|
||||
uint p, b0, b1;
|
||||
Rune r;
|
||||
|
||||
/* advance to p0 */
|
||||
b0 = 0;
|
||||
for(p=0; p<p0 && b0<ntypeb; p++){
|
||||
w = chartorune(&r, typing+b0);
|
||||
b0 += w;
|
||||
}
|
||||
if(p != p0)
|
||||
error("deltype 1");
|
||||
/* advance to p1 */
|
||||
b1 = b0;
|
||||
for(; p<p1 && b1<ntypeb; p++){
|
||||
w = chartorune(&r, typing+b1);
|
||||
b1 += w;
|
||||
if(r=='\n' || r==0x04)
|
||||
ntypebreak--;
|
||||
}
|
||||
if(p != p1)
|
||||
error("deltype 2");
|
||||
memmove(typing+b0, typing+b1, ntypeb-b1);
|
||||
ntypeb -= b1-b0;
|
||||
ntyper -= p1-p0;
|
||||
}
|
||||
|
||||
void
|
||||
type(Event *e, int fd0, int afd, int dfd)
|
||||
{
|
||||
int m, n, nr;
|
||||
char buf[128];
|
||||
|
||||
if(e->nr > 0)
|
||||
addtype(e->c1, e->q0-q.p, e->b, e->nb, e->nr);
|
||||
else{
|
||||
m = e->q0;
|
||||
while(m < e->q1){
|
||||
n = sprint(buf, "#%d", m);
|
||||
write(afd, buf, n);
|
||||
n = read(dfd, buf, sizeof buf);
|
||||
nr = nrunes(buf, n);
|
||||
while(m+nr > e->q1){
|
||||
do; while(n>0 && (buf[--n]&0xC0)==0x80);
|
||||
--nr;
|
||||
}
|
||||
if(n == 0)
|
||||
break;
|
||||
addtype(e->c1, m-q.p, buf, n, nr);
|
||||
m += nr;
|
||||
}
|
||||
}
|
||||
sendtype(fd0);
|
||||
}
|
||||
|
||||
void
|
||||
sende(Event *e, int fd0, int cfd, int afd, int dfd, int donl)
|
||||
{
|
||||
int l, m, n, nr, lastc, end;
|
||||
char abuf[16], buf[128];
|
||||
|
||||
end = q.p+ntyper;
|
||||
l = sprint(abuf, "#%d", end);
|
||||
write(afd, abuf, l);
|
||||
if(e->nr > 0){
|
||||
write(dfd, e->b, e->nb);
|
||||
addtype(e->c1, ntyper, e->b, e->nb, e->nr);
|
||||
lastc = e->r[e->nr-1];
|
||||
}else{
|
||||
m = e->q0;
|
||||
lastc = 0;
|
||||
while(m < e->q1){
|
||||
n = sprint(buf, "#%d", m);
|
||||
write(afd, buf, n);
|
||||
n = read(dfd, buf, sizeof buf);
|
||||
nr = nrunes(buf, n);
|
||||
while(m+nr > e->q1){
|
||||
do; while(n>0 && (buf[--n]&0xC0)==0x80);
|
||||
--nr;
|
||||
}
|
||||
if(n == 0)
|
||||
break;
|
||||
l = sprint(abuf, "#%d", end);
|
||||
write(afd, abuf, l);
|
||||
write(dfd, buf, n);
|
||||
addtype(e->c1, ntyper, buf, n, nr);
|
||||
lastc = buf[n-1];
|
||||
m += nr;
|
||||
end += nr;
|
||||
}
|
||||
}
|
||||
if(donl && lastc!='\n'){
|
||||
write(dfd, "\n", 1);
|
||||
addtype(e->c1, ntyper, "\n", 1, 1);
|
||||
}
|
||||
write(cfd, "dot=addr", 8);
|
||||
sendtype(fd0);
|
||||
}
|
Loading…
Reference in a new issue