int assemble(char *file) { char *ofile, *p; int i, of; ofile = alloc(strlen(file)+3); // +3 for .x\0 (x=thechar) strcpy(ofile, file); p = utfrrune(ofile, pathchar()); if(p) { include[0] = ofile; *p++ = 0; } else p = ofile; if(outfile == 0) { outfile = p; if(outfile){ p = utfrrune(outfile, '.'); if(p) if(p[1] == 's' && p[2] == 0) p[0] = 0; p = utfrune(outfile, 0); p[0] = '.'; p[1] = thechar; p[2] = 0; } else outfile = "/dev/null"; } of = create(outfile, OWRITE, 0664); if(of < 0) { yyerror("%ca: cannot create %s", thechar, outfile); errorexit(); } Binit(&obuf, of, OWRITE); pass = 1; pinit(file); Bprint(&obuf, "go object %s %s %s\n", getgoos(), thestring, getgoversion()); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); if(nerrors) { cclean(); return nerrors; } Bprint(&obuf, "\n!\n"); pass = 2; outhist(); pinit(file); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); cclean(); return nerrors; }
void mkdir(char *name, uint32_t mode, uint32_t mtime, char *uid, char *gid) { Dir *d, xd; int fd; char *p; char olderr[256]; fd = create(name, OREAD, mode); if(fd < 0){ rerrstr(olderr, sizeof(olderr)); if((d = dirstat(name)) == nil || !(d->mode & DMDIR)){ free(d); warn("can't make directory %q, mode %luo: %s", name, mode, olderr); return; } free(d); } close(fd); d = &xd; nulldir(d); p = utfrrune(name, L'/'); if(p) p++; else p = name; d->name = p; if(uflag){ d->uid = uid; d->gid = gid; } if(Tflag) d->mtime = mtime; d->mode = mode; if(dirwstat(name, d) < 0) warn("can't set modes for %q: %r", name); if(uflag||Tflag){ if((d = dirstat(name)) == nil){ warn("can't reread modes for %q: %r", name); return; } if(Tflag && d->mtime != mtime) warn("%q: time mismatch %lu %lu\n", name, mtime, d->mtime); if(uflag && strcmp(uid, d->uid)) warn("%q: uid mismatch %q %q", name, uid, d->uid); if(uflag && strcmp(gid, d->gid)) warn("%q: gid mismatch %q %q", name, gid, d->gid); } }
void split(char *name, char **pdir, char **pelem) { char *s; s = utfrrune(name, '/'); if(s){ *s = 0; *pelem = s+1; *pdir = name; }else if(strcmp(name, "..") == 0){ *pdir = ".."; *pelem = "."; }else{ *pdir = "."; *pelem = name; } }
ulong mkmtime(char *name, int force) { Dir *d; char *s, *ss, carry; ulong t; Symtab *sym; char buf[4096]; strecpy(buf, buf + sizeof buf - 1, name); cleanname(buf); name = buf; s = utfrrune(name, '/'); if(s == name) s++; if(s){ ss = name; carry = *s; *s = 0; }else{ ss = 0; carry = 0; } bulkmtime(ss); if(carry) *s = carry; if(!force){ sym = symlook(name, S_TIME, 0); if(sym) return sym->u.value; return 0; } if((d = dirstat(name)) == nil) return 0; t = d->mtime; free(d); return t; }
Mousectl* initmouse(char *file, Image *i) { Mousectl *mc; char *t, *sl; mc = mallocz(sizeof(Mousectl), 1); if(file == nil) file = "/dev/mouse"; mc->file = strdup(file); mc->mfd = open(file, ORDWR|OCEXEC); if(mc->mfd<0 && strcmp(file, "/dev/mouse")==0){ bind("#m", "/dev", MAFTER); mc->mfd = open(file, ORDWR|OCEXEC); } if(mc->mfd < 0){ free(mc); return nil; } t = malloc(strlen(file)+16); if (t == nil) { close(mc->mfd); free(mc); return nil; } strcpy(t, file); sl = utfrrune(t, '/'); if(sl) strcpy(sl, "/cursor"); else strcpy(t, "/dev/cursor"); mc->cfd = open(t, ORDWR|OCEXEC); free(t); mc->image = i; mc->c = chancreate(sizeof(Mouse), 0); mc->resizec = chancreate(sizeof(int), 2); proccreate(_ioproc, mc, 4096); return mc; }
void main(int argc, char *argv[]) { char *pr; int n, dflag; dflag = 0; if(argc>1 && strcmp(argv[1], "-d") == 0){ --argc; ++argv; dflag = 1; } if(argc < 2 || argc > 3){ fprint(2, "usage: basename [-d] string [suffix]\n"); exits("usage"); } pr = utfrrune(argv[1], '/'); if(dflag){ if(pr){ *pr = 0; print("%s\n", argv[1]); exits(0); } print(".\n"); exits(0); } if(pr) pr++; else pr = argv[1]; if(argc==3){ n = strlen(pr)-strlen(argv[2]); if(n >= 0 && !strcmp(pr+n, argv[2])) pr[n] = 0; } print("%s\n", pr); exits(0); }
int assemble(char *file) { char ofile[100], incfile[20], *p; int i, of; strcpy(ofile, file); p = utfrrune(ofile, pathchar()); if(p) { include[0] = ofile; *p++ = 0; } else p = ofile; if(outfile == 0) { outfile = p; if(outfile){ p = utfrrune(outfile, '.'); if(p) if(p[1] == 's' && p[2] == 0) p[0] = 0; p = utfrune(outfile, 0); p[0] = '.'; p[1] = thechar; p[2] = 0; } else outfile = "/dev/null"; } p = getenv("INCLUDE"); if(p) { setinclude(p); } else { if(systemtype(Plan9)) { sprint(incfile,"/%s/include", thestring); setinclude(strdup(incfile)); } } of = mycreat(outfile, 0664); if(of < 0) { yyerror("%ca: cannot create %s", thechar, outfile); errorexit(); } Binit(&obuf, of, OWRITE); pass = 1; pinit(file); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); if(nerrors) { cclean(); return nerrors; } pass = 2; outhist(); pinit(file); for(i=0; i<nDlist; i++) dodefine(Dlist[i]); yyparse(); cclean(); return nerrors; }
void exprfmt(Fmt *f, Node *n, int prec) { int nprec; char *p; nprec = 0; if(n == nil) { fmtprint(f, "<nil>"); return; } if(n->implicit) { exprfmt(f, n->left, prec); return; } switch(n->op) { case OAPPEND: case ONAME: case ONONAME: case OPACK: case OLITERAL: case ODOT: case ODOTPTR: case ODOTINTER: case ODOTMETH: case ODOTTYPE: case ODOTTYPE2: case OXDOT: case OARRAYBYTESTR: case OCAP: case OCLOSE: case OCOPY: case OLEN: case OMAKE: case ONEW: case OPANIC: case OPRINT: case OPRINTN: case OCALL: case OCALLMETH: case OCALLINTER: case OCALLFUNC: case OCONV: case OCONVNOP: case OMAKESLICE: case ORUNESTR: case OADDR: case OCOM: case OIND: case OMINUS: case ONOT: case OPLUS: case ORECV: case OCONVIFACE: case OTPAREN: case OINDEX: case OINDEXMAP: nprec = 7; break; case OMUL: case ODIV: case OMOD: case OLSH: case ORSH: case OAND: case OANDNOT: nprec = 6; break; case OADD: case OSUB: case OOR: case OXOR: nprec = 5; break; case OEQ: case OLT: case OLE: case OGE: case OGT: case ONE: nprec = 4; break; case OSEND: nprec = 3; break; case OANDAND: nprec = 2; break; case OOROR: nprec = 1; break; case OTYPE: if(n->sym != S) nprec = 7; break; } if(prec > nprec) fmtprint(f, "("); switch(n->op) { default: bad: fmtprint(f, "(node %O)", n->op); break; case OLITERAL: if(n->sym != S) { fmtprint(f, "%S", n->sym); break; } switch(n->val.ctype) { default: goto bad; case CTINT: fmtprint(f, "%B", n->val.u.xval); break; case CTBOOL: if(n->val.u.bval) fmtprint(f, "true"); else fmtprint(f, "false"); break; case CTCPLX: fmtprint(f, "%.17g+%.17gi", mpgetflt(&n->val.u.cval->real), mpgetflt(&n->val.u.cval->imag)); break; case CTFLT: fmtprint(f, "%.17g", mpgetflt(n->val.u.fval)); break; case CTSTR: fmtprint(f, "\"%Z\"", n->val.u.sval); break; case CTNIL: fmtprint(f, "nil"); break; } break; case ONAME: case OPACK: case ONONAME: fmtprint(f, "%S", n->sym); break; case OTYPE: if(n->type == T && n->sym != S) { fmtprint(f, "%S", n->sym); break; } fmtprint(f, "%T", n->type); break; case OTARRAY: fmtprint(f, "[]"); exprfmt(f, n->left, PFIXME); break; case OTPAREN: fmtprint(f, "("); exprfmt(f, n->left, 0); fmtprint(f, ")"); break; case OTMAP: fmtprint(f, "map["); exprfmt(f, n->left, 0); fmtprint(f, "] "); exprfmt(f, n->right, 0); break; case OTCHAN: if(n->etype == Crecv) fmtprint(f, "<-"); fmtprint(f, "chan"); if(n->etype == Csend) { fmtprint(f, "<- "); exprfmt(f, n->left, 0); } else { fmtprint(f, " "); if(n->left->op == OTCHAN && n->left->sym == S && n->left->etype == Crecv) { fmtprint(f, "("); exprfmt(f, n->left, 0); fmtprint(f, ")"); } else exprfmt(f, n->left, 0); } break; case OTSTRUCT: fmtprint(f, "<struct>"); break; case OTINTER: fmtprint(f, "<inter>"); break; case OTFUNC: fmtprint(f, "<func>"); break; case OAS: exprfmt(f, n->left, 0); fmtprint(f, " = "); exprfmt(f, n->right, 0); break; case OASOP: exprfmt(f, n->left, 0); fmtprint(f, " %#O= ", n->etype); exprfmt(f, n->right, 0); break; case OADD: case OANDAND: case OANDNOT: case ODIV: case OEQ: case OGE: case OGT: case OLE: case OLT: case OLSH: case OMOD: case OMUL: case ONE: case OOR: case OOROR: case ORSH: case OSEND: case OSUB: case OXOR: exprfmt(f, n->left, nprec); fmtprint(f, " %#O ", n->op); exprfmt(f, n->right, nprec+1); break; case OADDR: case OCOM: case OIND: case OMINUS: case ONOT: case OPLUS: case ORECV: fmtprint(f, "%#O", n->op); if((n->op == OMINUS || n->op == OPLUS) && n->left->op == n->op) fmtprint(f, " "); exprfmt(f, n->left, 0); break; case OCLOSURE: fmtprint(f, "func literal"); break; case OCOMPLIT: fmtprint(f, "composite literal"); break; case OARRAYLIT: if(isslice(n->type)) fmtprint(f, "slice literal"); else fmtprint(f, "array literal"); break; case OMAPLIT: fmtprint(f, "map literal"); break; case OSTRUCTLIT: fmtprint(f, "struct literal"); break; case OXDOT: case ODOT: case ODOTPTR: case ODOTINTER: case ODOTMETH: exprfmt(f, n->left, 7); if(n->right == N || n->right->sym == S) fmtprint(f, ".<nil>"); else { // skip leading type· in method name p = utfrrune(n->right->sym->name, 0xb7); if(p) p+=2; else p = n->right->sym->name; fmtprint(f, ".%s", p); } break; case ODOTTYPE: case ODOTTYPE2: exprfmt(f, n->left, 7); fmtprint(f, ".("); if(n->right != N) exprfmt(f, n->right, 0); else fmtprint(f, "%T", n->type); fmtprint(f, ")"); break; case OINDEX: case OINDEXMAP: exprfmt(f, n->left, 7); fmtprint(f, "["); exprfmt(f, n->right, 0); fmtprint(f, "]"); break; case OSLICE: case OSLICESTR: case OSLICEARR: exprfmt(f, n->left, 7); fmtprint(f, "["); if(n->right->left != N) exprfmt(f, n->right->left, 0); fmtprint(f, ":"); if(n->right->right != N) exprfmt(f, n->right->right, 0); fmtprint(f, "]"); break; case OCALL: case OCALLFUNC: case OCALLINTER: case OCALLMETH: exprfmt(f, n->left, 7); fmtprint(f, "("); exprlistfmt(f, n->list); if(n->isddd) fmtprint(f, "..."); fmtprint(f, ")"); break; case OCOMPLEX: fmtprint(f, "complex("); exprfmt(f, n->left, 0); fmtprint(f, ", "); exprfmt(f, n->right, 0); fmtprint(f, ")"); break; case OREAL: fmtprint(f, "real("); exprfmt(f, n->left, 0); fmtprint(f, ")"); break; case OIMAG: fmtprint(f, "imag("); exprfmt(f, n->left, 0); fmtprint(f, ")"); break; case OCONV: case OCONVIFACE: case OCONVNOP: case OARRAYBYTESTR: case ORUNESTR: if(n->type == T || n->type->sym == S) fmtprint(f, "(%T)(", n->type); else fmtprint(f, "%T(", n->type); if(n->left == N) exprlistfmt(f, n->list); else exprfmt(f, n->left, 0); fmtprint(f, ")"); break; case OAPPEND: case OCAP: case OCLOSE: case OLEN: case OCOPY: case OMAKE: case ONEW: case OPANIC: case OPRINT: case OPRINTN: fmtprint(f, "%#O(", n->op); if(n->left) exprfmt(f, n->left, 0); else exprlistfmt(f, n->list); fmtprint(f, ")"); break; case OMAKESLICE: fmtprint(f, "make(%#T, ", n->type); exprfmt(f, n->left, 0); if(count(n->list) > 2) { fmtprint(f, ", "); exprfmt(f, n->right, 0); } fmtprint(f, ")"); break; case OMAKEMAP: fmtprint(f, "make(%#T)", n->type); break; } if(prec > nprec) fmtprint(f, ")"); }
void threadmain(int argc, char *argv[]) { int i; char *p, *loadfile; Column *c; int ncol; Display *d; rfork(RFENVG|RFNAMEG); ncol = -1; loadfile = nil; ARGBEGIN{ case 'D': {extern int _threaddebuglevel; _threaddebuglevel = ~0; } break; case 'a': globalautoindent = TRUE; break; case 'b': bartflag = TRUE; break; case 'c': p = ARGF(); if(p == nil) goto Usage; ncol = atoi(p); if(ncol <= 0) goto Usage; break; case 'f': fontnames[0] = ARGF(); if(fontnames[0] == nil) goto Usage; break; case 'F': fontnames[1] = ARGF(); if(fontnames[1] == nil) goto Usage; break; case 'l': loadfile = ARGF(); if(loadfile == nil) goto Usage; break; case 'm': mtpt = ARGF(); if(mtpt == nil) goto Usage; break; case 'r': swapscrollbuttons = TRUE; break; case 'W': winsize = ARGF(); if(winsize == nil) goto Usage; break; default: Usage: fprint(2, "usage: acme -a -c ncol -f fontname -F fixedwidthfontname -l loadfile -W winsize\n"); threadexitsall("usage"); }ARGEND fontnames[0] = estrdup(fontnames[0]); fontnames[1] = estrdup(fontnames[1]); quotefmtinstall(); fmtinstall('t', timefmt); cputype = getenv("cputype"); objtype = getenv("objtype"); home = getenv("HOME"); acmeshell = getenv("acmeshell"); if(acmeshell && *acmeshell == '\0') acmeshell = nil; p = getenv("tabstop"); if(p != nil){ maxtab = strtoul(p, nil, 0); free(p); } if(maxtab == 0) maxtab = 4; if(loadfile) rowloadfonts(loadfile); putenv("font", fontnames[0]); snarffd = open("/dev/snarf", OREAD|OCEXEC); /* if(cputype){ sprint(buf, "/acme/bin/%s", cputype); bind(buf, "/bin", MBEFORE); } bind("/acme/bin", "/bin", MBEFORE); */ getwd(wdir, sizeof wdir); /* if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){ fprint(2, "acme: can't open display: %r\n"); threadexitsall("geninitdraw"); } */ if(initdraw(derror, fontnames[0], "acme") < 0){ fprint(2, "acme: can't open display: %r\n"); threadexitsall("initdraw"); } d = display; font = d->defaultfont; /*assert(font); */ reffont.f = font; reffonts[0] = &reffont; incref(&reffont.ref); /* one to hold up 'font' variable */ incref(&reffont.ref); /* one to hold up reffonts[0] */ fontcache = emalloc(sizeof(Reffont*)); nfontcache = 1; fontcache[0] = &reffont; iconinit(); timerinit(); rxinit(); cwait = threadwaitchan(); ccommand = chancreate(sizeof(Command**), 0); ckill = chancreate(sizeof(Rune*), 0); cxfidalloc = chancreate(sizeof(Xfid*), 0); cxfidfree = chancreate(sizeof(Xfid*), 0); cnewwindow = chancreate(sizeof(Channel*), 0); cerr = chancreate(sizeof(char*), 0); cedit = chancreate(sizeof(int), 0); cexit = chancreate(sizeof(int), 0); cwarn = chancreate(sizeof(void*), 1); if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){ fprint(2, "acme: can't create initial channels: %r\n"); threadexitsall("channels"); } chansetname(ccommand, "ccommand"); chansetname(ckill, "ckill"); chansetname(cxfidalloc, "cxfidalloc"); chansetname(cxfidfree, "cxfidfree"); chansetname(cnewwindow, "cnewwindow"); chansetname(cerr, "cerr"); chansetname(cedit, "cedit"); chansetname(cexit, "cexit"); chansetname(cwarn, "cwarn"); mousectl = initmouse(nil, screen); if(mousectl == nil){ fprint(2, "acme: can't initialize mouse: %r\n"); threadexitsall("mouse"); } mouse = &mousectl->m; keyboardctl = initkeyboard(nil); if(keyboardctl == nil){ fprint(2, "acme: can't initialize keyboard: %r\n"); threadexitsall("keyboard"); } mainpid = getpid(); startplumbing(); /* plumbeditfd = plumbopen("edit", OREAD|OCEXEC); if(plumbeditfd < 0) fprint(2, "acme: can't initialize plumber: %r\n"); else{ cplumb = chancreate(sizeof(Plumbmsg*), 0); threadcreate(plumbproc, nil, STACK); } plumbsendfd = plumbopen("send", OWRITE|OCEXEC); */ fsysinit(); #define WPERCOL 8 disk = diskinit(); if(!loadfile || !rowload(&row, loadfile, TRUE)){ rowinit(&row, screen->clipr); if(ncol < 0){ if(argc == 0) ncol = 2; else{ ncol = (argc+(WPERCOL-1))/WPERCOL; if(ncol < 2) ncol = 2; } } if(ncol == 0) ncol = 2; for(i=0; i<ncol; i++){ c = rowadd(&row, nil, -1); if(c==nil && i==0) error("initializing columns"); } c = row.col[row.ncol-1]; if(argc == 0) readfile(c, wdir); else for(i=0; i<argc; i++){ p = utfrrune(argv[i], '/'); if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol) readfile(c, argv[i]); else readfile(row.col[i/WPERCOL], argv[i]); } } flushimage(display, 1); acmeerrorinit(); threadcreate(keyboardthread, nil, STACK); threadcreate(mousethread, nil, STACK); threadcreate(waitthread, nil, STACK); threadcreate(xfidallocthread, nil, STACK); threadcreate(newwindowthread, nil, STACK); /* threadcreate(shutdownthread, nil, STACK); */ threadnotify(shutdown, 1); recvul(cexit); killprocs(); threadexitsall(nil); }
void extract(char *name, uint32_t mode, uint32_t mtime, char *uid, char *gid, uint64_t bytes) { Dir d, *nd; Biobuf *b; char buf[LEN]; char *p; uint32_t n; uint64_t tot; if(vflag) print("x %q %llu bytes\n", name, bytes); b = Bopen(name, OWRITE); if(!b){ warn("can't make file %q: %r", name); seekpast(bytes); return; } for(tot = 0; tot < bytes; tot += n){ n = sizeof buf; if(tot + n > bytes) n = bytes - tot; n = Bread(&bin, buf, n); if(n <= 0) error("premature eof reading %q", name); if(Bwrite(b, buf, n) != n) warn("error writing %q: %r", name); } nulldir(&d); p = utfrrune(name, '/'); if(p) p++; else p = name; d.name = p; if(uflag){ d.uid = uid; d.gid = gid; } if(Tflag) d.mtime = mtime; d.mode = mode; Bflush(b); if(dirfwstat(Bfildes(b), &d) < 0) warn("can't set modes for %q: %r", name); if(uflag||Tflag){ if((nd = dirfstat(Bfildes(b))) == nil) warn("can't reread modes for %q: %r", name); else{ if(Tflag && nd->mtime != mtime) warn("%q: time mismatch %lu %lu\n", name, mtime, nd->mtime); if(uflag && strcmp(uid, nd->uid)) warn("%q: uid mismatch %q %q", name, uid, nd->uid); if(uflag && strcmp(gid, nd->gid)) warn("%q: gid mismatch %q %q", name, gid, nd->gid); free(nd); } } Bterm(b); }
void threadmain(int argc, char *argv[]) { int i, j; char *dir, *tag, *name; char buf[1024], **av; quotefmtinstall(); rfork(RFNAMEG); ARGBEGIN{ case 'd': debug = 1; chatty9p++; break; case 'e': eraseinput = 1; break; case 'D': {extern int _threaddebuglevel; _threaddebuglevel = 1<<20; } }ARGEND if(argc == 0){ av = emalloc(3*sizeof(char*)); av[0] = "rc"; av[1] = "-i"; name = getenv("sysname"); }else{ av = argv; name = utfrrune(av[0], '/'); if(name) name++; else name = av[0]; } if(getwd(buf, sizeof buf) == 0) dir = "/"; else dir = buf; dir = estrdup(dir); tag = estrdup(dir); tag = eappend(estrdup(tag), "/-", name); win = newwindow(); snprint(buf, sizeof buf, "%d", win->id); putenv("winid", buf); winname(win, tag); wintagwrite(win, "Send Noscroll", 5+8); threadcreate(mainctl, win, STACK); mountcons(); threadcreate(fsloop, nil, STACK); startpipe(); startcmd(av, ¬epg); strcpy(buf, "win"); j = 3; for(i=0; i<argc && j+1+strlen(argv[i])+1<sizeof buf; i++){ strcpy(buf+j, " "); strcpy(buf+j+1, argv[i]); j += 1+strlen(argv[i]); } ctlprint(win->ctl, "scroll"); winsetdump(win, dir, buf); }
void threadmain(int argc, char *argv[]) { int i; char *p, *loadfile; char buf[256]; Column *c; int ncol; Display *d; static void *arg[1]; rfork(RFENVG|RFNAMEG); ncol = -1; loadfile = nil; ARGBEGIN{ case 'a': globalautoindent = TRUE; break; case 'b': bartflag = TRUE; break; case 'c': p = ARGF(); if(p == nil) goto Usage; ncol = atoi(p); if(ncol <= 0) goto Usage; break; case 'f': fontnames[0] = ARGF(); if(fontnames[0] == nil) goto Usage; break; case 'F': fontnames[1] = ARGF(); if(fontnames[1] == nil) goto Usage; break; case 'l': loadfile = ARGF(); if(loadfile == nil) goto Usage; break; default: Usage: fprint(2, "usage: acme [-ab] [-c ncol] [-f font] [-F fixedfont] [-l loadfile | file...]\n"); exits("usage"); }ARGEND if(fontnames[0] == nil) fontnames[0] = getenv("font"); if(fontnames[0] == nil) fontnames[0] = "/lib/font/bit/vga/unicode.font"; if(access(fontnames[0], 0) < 0){ fprint(2, "acme: can't access %s: %r\n", fontnames[0]); exits("font open"); } if(fontnames[1] == nil) fontnames[1] = fontnames[0]; fontnames[0] = estrdup(fontnames[0]); fontnames[1] = estrdup(fontnames[1]); quotefmtinstall(); cputype = getenv("cputype"); objtype = getenv("objtype"); home = getenv("home"); p = getenv("tabstop"); if(p != nil){ maxtab = strtoul(p, nil, 0); free(p); } if(maxtab == 0) maxtab = 4; if(loadfile) rowloadfonts(loadfile); putenv("font", fontnames[0]); snarffd = open("/dev/snarf", OREAD|OCEXEC); if(cputype){ sprint(buf, "/acme/bin/%s", cputype); bind(buf, "/bin", MBEFORE); } bind("/acme/bin", "/bin", MBEFORE); getwd(wdir, sizeof wdir); if(geninitdraw(nil, derror, fontnames[0], "acme", nil, Refnone) < 0){ fprint(2, "acme: can't open display: %r\n"); exits("geninitdraw"); } d = display; font = d->defaultfont; reffont.f = font; reffonts[0] = &reffont; incref(&reffont); /* one to hold up 'font' variable */ incref(&reffont); /* one to hold up reffonts[0] */ fontcache = emalloc(sizeof(Reffont*)); nfontcache = 1; fontcache[0] = &reffont; iconinit(); timerinit(); rxinit(); cwait = threadwaitchan(); ccommand = chancreate(sizeof(Command**), 0); ckill = chancreate(sizeof(Rune*), 0); cxfidalloc = chancreate(sizeof(Xfid*), 0); cxfidfree = chancreate(sizeof(Xfid*), 0); cnewwindow = chancreate(sizeof(Channel*), 0); cerr = chancreate(sizeof(char*), 0); cedit = chancreate(sizeof(int), 0); cexit = chancreate(sizeof(int), 0); cwarn = chancreate(sizeof(void*), 1); if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){ fprint(2, "acme: can't create initial channels: %r\n"); threadexitsall("channels"); } mousectl = initmouse(nil, screen); if(mousectl == nil){ fprint(2, "acme: can't initialize mouse: %r\n"); threadexitsall("mouse"); } mouse = mousectl; keyboardctl = initkeyboard(nil); if(keyboardctl == nil){ fprint(2, "acme: can't initialize keyboard: %r\n"); threadexitsall("keyboard"); } mainpid = getpid(); plumbeditfd = plumbopen("edit", OREAD|OCEXEC); if(plumbeditfd >= 0){ cplumb = chancreate(sizeof(Plumbmsg*), 0); proccreate(plumbproc, nil, STACK); } plumbsendfd = plumbopen("send", OWRITE|OCEXEC); fsysinit(); #define WPERCOL 8 disk = diskinit(); if(!loadfile || !rowload(&row, loadfile, TRUE)){ rowinit(&row, screen->clipr); if(ncol < 0){ if(argc == 0) ncol = 2; else{ ncol = (argc+(WPERCOL-1))/WPERCOL; if(ncol < 2) ncol = 2; } } if(ncol == 0) ncol = 2; for(i=0; i<ncol; i++){ c = rowadd(&row, nil, -1); if(c==nil && i==0) error("initializing columns"); } c = row.col[row.ncol-1]; if(argc == 0) readfile(c, wdir); else for(i=0; i<argc; i++){ p = utfrrune(argv[i], '/'); if((p!=nil && strcmp(p, "/guide")==0) || i/WPERCOL>=row.ncol) readfile(c, argv[i]); else readfile(row.col[i/WPERCOL], argv[i]); } } flushimage(display, 1); acmeerrorinit(); threadcreate(keyboardthread, nil, STACK); threadcreate(mousethread, nil, STACK); threadcreate(waitthread, nil, STACK); threadcreate(xfidallocthread, nil, STACK); threadcreate(newwindowthread, nil, STACK); threadnotify(shutdown, 1); recvul(cexit); killprocs(); threadexitsall(nil); }