Fighting the good fight.
Move libfmt, libutf into subdirectories of lib9. Add poll-based socket i/o to libthread, so that we can avoid using multiple procs when possible, thus removing dependence on crappy pthreads implementations. Convert samterm, acme to the single-proc libthread. Bring libcomplete, acme up-to-date w.r.t. Plan 9 distribution.
This commit is contained in:
parent
d51419bf43
commit
5a8e63b2f0
107 changed files with 665 additions and 6637 deletions
|
|
@ -62,9 +62,11 @@ errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
|
|||
int i, n;
|
||||
static Rune Lpluserrors[] = { '+', 'E', 'r', 'r', 'o', 'r', 's', 0 };
|
||||
|
||||
r = runemalloc(ndir+7);
|
||||
if(n = ndir) /* assign = */
|
||||
r = runemalloc(ndir+8);
|
||||
if(n = ndir){ /* assign = */
|
||||
runemove(r, dir, ndir);
|
||||
r[n++] = L'/';
|
||||
}
|
||||
runemove(r+n, Lpluserrors, 7);
|
||||
n += 7;
|
||||
w = lookfile(r, n);
|
||||
|
|
@ -83,12 +85,13 @@ errorwin1(Rune *dir, int ndir, Rune **incl, int nincl)
|
|||
runemove(r, incl[i], n);
|
||||
winaddincl(w, r, n);
|
||||
}
|
||||
w->autoindent = globalautoindent;
|
||||
return w;
|
||||
}
|
||||
|
||||
/* make new window, if necessary; return with it locked */
|
||||
Window*
|
||||
errorwin(Mntdir *md, int owner, Window *e)
|
||||
errorwin(Mntdir *md, int owner)
|
||||
{
|
||||
Window *w;
|
||||
|
||||
|
|
@ -97,51 +100,100 @@ errorwin(Mntdir *md, int owner, Window *e)
|
|||
w = errorwin1(nil, 0, nil, 0);
|
||||
else
|
||||
w = errorwin1(md->dir, md->ndir, md->incl, md->nincl);
|
||||
if(w != e)
|
||||
winlock(w, owner);
|
||||
winlock(w, owner);
|
||||
if(w->col != nil)
|
||||
break;
|
||||
/* window was deleted too fast */
|
||||
if(w != e)
|
||||
winunlock(w);
|
||||
winunlock(w);
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
static void
|
||||
printwarning(Window *ew, Mntdir *md, Rune *r)
|
||||
typedef struct Warning Warning;
|
||||
|
||||
struct Warning{
|
||||
Mntdir *md;
|
||||
Buffer buf;
|
||||
Warning *next;
|
||||
};
|
||||
|
||||
static Warning *warnings;
|
||||
|
||||
static
|
||||
void
|
||||
addwarningtext(Mntdir *md, Rune *r, int nr)
|
||||
{
|
||||
int nr, q0, owner;
|
||||
Warning *warn;
|
||||
|
||||
for(warn = warnings; warn; warn=warn->next){
|
||||
if(warn->md == md){
|
||||
bufinsert(&warn->buf, warn->buf.nc, r, nr);
|
||||
return;
|
||||
}
|
||||
}
|
||||
warn = emalloc(sizeof(Warning));
|
||||
warn->next = warnings;
|
||||
warnings = warn;
|
||||
bufinsert(&warn->buf, 0, r, nr);
|
||||
}
|
||||
|
||||
void
|
||||
flushwarnings(int dolock)
|
||||
{
|
||||
Warning *warn, *next;
|
||||
Window *w;
|
||||
Text *t;
|
||||
int owner, nr, q0, n;
|
||||
Rune *r;
|
||||
|
||||
if(r == nil)
|
||||
error("runevsmprint failed");
|
||||
nr = runestrlen(r);
|
||||
|
||||
if(dolock)
|
||||
qlock(&row.lk);
|
||||
if(row.ncol == 0){ /* really early error */
|
||||
rowinit(&row, screen->clipr);
|
||||
rowadd(&row, nil, -1);
|
||||
rowadd(&row, nil, -1);
|
||||
if(row.ncol == 0)
|
||||
error("initializing columns in warning()");
|
||||
error("initializing columns in flushwarnings()");
|
||||
}
|
||||
|
||||
w = errorwin(md, 'E', ew);
|
||||
t = &w->body;
|
||||
owner = w->owner;
|
||||
if(owner == 0)
|
||||
w->owner = 'E';
|
||||
wincommit(w, t);
|
||||
q0 = textbsinsert(t, t->file->b.nc, r, nr, TRUE, &nr);
|
||||
textshow(t, q0, q0+nr, 1);
|
||||
winsettag(t->w);
|
||||
textscrdraw(t);
|
||||
w->owner = owner;
|
||||
w->dirty = FALSE;
|
||||
if(ew != w)
|
||||
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->b.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->b.nc, r, nr, TRUE, &nr);
|
||||
}
|
||||
textshow(t, q0, t->file->b.nc, 1);
|
||||
free(r);
|
||||
winsettag(t->w);
|
||||
textscrdraw(t);
|
||||
w->owner = owner;
|
||||
w->dirty = FALSE;
|
||||
winunlock(w);
|
||||
free(r);
|
||||
bufclose(&warn->buf);
|
||||
next = warn->next;
|
||||
free(warn);
|
||||
}
|
||||
warnings = nil;
|
||||
if(dolock)
|
||||
qunlock(&row.lk);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -153,23 +205,9 @@ warning(Mntdir *md, char *s, ...)
|
|||
va_start(arg, s);
|
||||
r = runevsmprint(s, arg);
|
||||
va_end(arg);
|
||||
printwarning(nil, md, r);
|
||||
}
|
||||
|
||||
/*
|
||||
* Warningew is like warning but avoids locking the error window
|
||||
* if it's already locked by checking that ew!=error window.
|
||||
*/
|
||||
void
|
||||
warningew(Window *ew, Mntdir *md, char *s, ...)
|
||||
{
|
||||
Rune *r;
|
||||
va_list arg;
|
||||
|
||||
va_start(arg, s);
|
||||
r = runevsmprint(s, arg);
|
||||
va_end(arg);
|
||||
printwarning(ew, md, r);
|
||||
if(r == nil)
|
||||
error("runevsmprint failed");
|
||||
addwarningtext(md, r, runestrlen(r));
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue