123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584 |
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <thread.h>
- #include "win.h"
- #include "adict.h"
- char *prog = "adict";
- char *lprog = "/bin/adict";
- char *xprog = "/bin/dict";
- char *dict, *pattern, *curaddr[MAXMATCH], *curone, *args[6], buffer[80];
- char abuffer[80], fbuffer[80], pbuffer[80];
- int curindex, count, Eopen, Mopen;
- Win Mwin, Ewin, Dwin;
- void openwin(char*, char*, Win*, int);
- void handle(Win*, int);
- void rexec(void*);
- void pexec(void*);
- int getaddr(char*);
- void
- usage(void)
- {
- threadprint(2, "usage: %s [-d dictname] [pattern]\n", argv0);
- threadexitsall(nil);
- }
- void
- threadmain(int argc, char** argv)
- {
- ARGBEGIN{
- case 'd':
- dict = strdup(ARGF());
- break;
- default:
- usage();
- }ARGEND
- /* if running as other name, note that fact */
- if(access(argv0, AEXIST) == 0)
- lprog = argv0;
- switch(argc){
- case 1:
- pattern = pbuffer;
- strcpy(pattern,argv[0]);
- if(dict == nil)
- dict = "oed";
- break;
- case 0:
- break;
- default:
- usage();
- }
- if ((dict == nil) && (pattern == nil))
- openwin(prog,"", &Dwin, Dictwin);
- if (pattern == nil)
- openwin(prog,"",&Ewin, Entrywin);
- if ((count = getaddr(pattern)) <= 1)
- openwin(prog,"Prev Next", &Ewin, Entrywin);
- else
- openwin(prog, "", &Mwin, Matchwin);
- }
- static int
- procrexec(char *xprog, ...)
- {
- int fpipe[2];
- void *rexarg[4];
- Channel *c;
- va_list va;
- int i;
- char *p;
- pipe(fpipe);
- va_start(va, xprog);
- p = xprog;
- for(i=0; p && i+1<nelem(args); i++){
- args[i] = p;
- p = va_arg(va, char*);
- }
- args[i] = nil;
- c = chancreate(sizeof(ulong), 0);
- rexarg[0] = xprog;
- rexarg[1] = args;
- rexarg[2] = fpipe;
- rexarg[3] = c;
- proccreate(rexec, rexarg, 8192);
- recvul(c);
- chanfree(c);
- close(fpipe[1]);
- return fpipe[0];
- }
- int
- getaddr(char *pattern)
- {
- /* Get char offset into dictionary of matches. */
- int fd, i;
- Biobuf inbuf;
- char *bufptr;
- char *obuf;
- if (pattern == nil) {
- curone = nil;
- curindex = 0;
- curaddr[curindex] = nil;
- return 0;
- }
- sprint(buffer,"/%s/A", pattern);
- fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
- Binit(&inbuf, fd, OREAD);
- i = 0;
- curindex = 0;
- while ((bufptr = Brdline(&inbuf, '\n')) != nil && (i < (MAXMATCH-1))) {
- bufptr[Blinelen(&inbuf)-1] = 0;
- obuf=bufptr;
- while (bufptr[0] != '#' && bufptr[0] != 0) bufptr++;
- if(bufptr[0] == 0)
- print("whoops buf «%s»\n", obuf);
- curaddr[i] = malloc(strlen(bufptr));
- strcpy(curaddr[i], bufptr);
- i++;
- }
- curaddr[i] = nil;
- if (i == MAXMATCH)
- threadprint(2, "Too many matches!\n");
- Bterm(&inbuf);
- close(fd);
- curone = curaddr[curindex];
- return(i);
- }
- char*
- getpattern(char *addr)
- {
- /* Get the pattern corresponding to an absolute address.*/
- int fd;
- char *res, *t;
- res = nil;
- sprint(buffer,"%sh", addr);
- fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
- if (read(fd, pbuffer, 80) > 80)
- threadprint(2, "Error in getting addres from dict.\n");
- else {
- t = pbuffer;
- /* remove trailing whitespace, newline */
- if (t != nil){
- while(*t != 0 && *t != '\n')
- t++;
- if(t == 0 && t > pbuffer)
- t--;
- while(t >= pbuffer && (*t==' ' || *t=='\n' || *t=='\t' || *t=='\r'))
- *t-- = 0;
- }
- res = pbuffer;
- }
- close(fd);
- return(res);
- }
- char*
- chgaddr(int dir)
- {
- /* Increment or decrement the current address (curone). */
- int fd;
- char *res, *t;
- res = nil;
- if (dir < 0)
- sprint(buffer,"%s-a", curone);
- else
- sprint(buffer,"%s+a", curone);
- fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
- if (read(fd, abuffer, 80) > 80)
- threadprint(2, "Error in getting addres from dict.\n");
- else {
- res = abuffer;
- while (*res != '#') res++;
- t = res;
- while ((*t != '\n') && (t != nil)) t++;
- if (t != nil) *t = 0;
- }
- close(fd);
- return(res);
- }
- void
- dispdicts(Win *cwin)
- {
- /* Display available dictionaries in window. */
- int fd, nb, i;
- char buf[1024], *t;
- fd = procrexec(xprog, "-d", "?", nil);
- wreplace(cwin, "0,$","",0); /* Clear window */
- while ((nb = read(fd, buf, 1024)) > 0) {
- t = buf;
- i = 0;
- if (strncmp("Usage", buf, 5) == 0) { /* Remove first line. */
- while (t[0] != '\n') {
- t++;
- i++;
- }
- t++;
- i++;
- }
- wwritebody(cwin, t, nb-i);
- }
- close(fd);
- wclean(cwin);
- }
- void
- dispentry(Win *cwin)
- {
- /* Display the current selection in window. */
- int fd, nb;
- char buf[BUFSIZE];
- if (curone == nil) {
- if (pattern != nil) {
- sprint(buf,"Pattern not found.\n");
- wwritebody(cwin, buf, 19);
- wclean(cwin);
- }
- return;
- }
- sprint(buffer,"%sp", curone);
- fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
- wreplace(cwin, "0,$","",0); /* Clear window */
- while ((nb = read(fd, buf, BUFSIZE)) > 0) {
- wwritebody(cwin, buf, nb);
- }
- close(fd);
- wclean(cwin);
- }
- void
- dispmatches(Win *cwin)
- {
- /* Display the current matches. */
- int fd, nb;
- char buf[BUFSIZE];
- sprint(buffer,"/%s/H", pattern);
- fd = procrexec(xprog, "-d", dict, "-c", buffer, nil);
- while ((nb = read(fd, buf, BUFSIZE)) > 0)
- wwritebody(cwin, buf, nb);
- close(fd);
- wclean(cwin);
- }
- char*
- format(char *s)
- {
- /* Format a string to be written in window tag. Acme doesn't like */
- /* non alpha-num's in the tag line. */
- char *t, *h;
- t = fbuffer;
- if (s == nil) {
- *t = 0;
- return t;
- }
- strcpy(t, s);
- h = t;
- while (*t != 0) {
- if (!(((*t >= 'a') && (*t <= 'z')) ||
- ((*t >= 'A') && (*t <= 'Z')) ||
- ((*t >= '0') && (*t <= '9'))))
- *t = '_';
- t++;
- }
- if (strlen(h) > MAXTAG)
- h[MAXTAG] = 0;
- if (strcmp(s,h) == 0) return s;
- return h;
- }
- void
- openwin(char *name, char *buttons, Win *twin, int wintype)
- {
- char buf[80];
- wnew(twin);
- if (wintype == Dictwin)
- sprint(buf,"%s",name);
- else
- if ((wintype == Entrywin) && (count > 1))
- sprint(buf,"%s/%s/%s/%d",name, dict, format(pattern), curindex+1);
- else
- sprint(buf,"%s/%s/%s",name, dict, format(pattern));
- wname(twin, buf);
- wtagwrite(twin, buttons, strlen(buttons));
- wclean(twin);
- wdormant(twin);
- if (wintype == Dictwin)
- dispdicts(twin);
- if (wintype == Matchwin) {
- Mopen = True;
- dispmatches(twin);
- }
- if (wintype == Entrywin) {
- Eopen = True;
- dispentry(twin);
- }
- handle(twin, wintype);
- }
- void
- vopenwin(void *v)
- {
- void **arg;
- char *name, *buttons;
- Win *twin;
- int wintype;
- arg = v;
- name = arg[0];
- buttons = arg[1];
- twin = arg[2];
- wintype = (int)arg[3];
- sendul(arg[4], 0);
- openwin(name, buttons, twin, wintype);
- threadexits(nil);
- }
-
- void
- procopenwin(char *name, char *buttons, Win *twin, int wintype)
- {
- void *arg[5];
- Channel *c;
- c = chancreate(sizeof(ulong), 0);
- arg[0] = name;
- arg[1] = buttons;
- arg[2] = twin;
- arg[3] = (void*)wintype;
- arg[4] = c;
- proccreate(vopenwin, arg, 8192);
- recvul(c);
- chanfree(c);
- }
- void
- rexec(void *v)
- {
- void **arg;
- char *prog;
- char **args;
- int *fd;
- Channel *c;
- arg = v;
- prog = arg[0];
- args = arg[1];
- fd = arg[2];
- c = arg[3];
- rfork(RFENVG|RFFDG);
- dup(fd[1], 1);
- close(fd[1]);
- close(fd[0]);
- procexec(c, prog, args);
- threadprint(2, "Remote pipe execution failed: %s %r\n", prog);
- abort();
- threadexits(nil);
- }
- void
- pexec(void *v)
- {
- void **arg;
- char *prog;
- char **args;
- Channel *c;
- arg = v;
- prog = arg[0];
- args = arg[1];
- c = arg[2];
- procexec(c, prog, args);
- threadprint(2, "Remote execution failed: %s %r\n", prog);
- abort();
- threadexits(nil);
- }
- void
- procpexec(char *prog, char **args)
- {
- void *rexarg[4];
- Channel *c;
- c = chancreate(sizeof(ulong), 0);
- rexarg[0] = prog;
- rexarg[1] = args;
- rexarg[2] = c;
- proccreate(pexec, rexarg, 8192);
- recvul(c);
- chanfree(c);
- }
- void
- kill(void)
- {
- /* Kill all processes related to this one. */
- int fd;
- sprint(buffer, "/proc/%d/notepg", getpid());
- fd = open(buffer, OWRITE);
- rfork(RFNOTEG);
- write(fd, "kill", 4);
- }
- int
- command(char *com, Win *w, int wintype)
- {
- char *buf;
- if (strncmp(com, "Del", 3) == 0) {
- switch(wintype){
- case Entrywin:
- if (wdel(w)) {
- Eopen = False;
- threadexits(nil);
- }
- break;
- case Dictwin:
- if (wdel(w))
- threadexits(nil);
- break;
- case Matchwin:
- kill();
- if (Eopen)
- if (~wdel(&Ewin)) /* Remove the entry window */
- wdel(&Ewin);
- if (!wdel(w))
- wdel(w);
- threadexits(nil);
- break;
- }
- return True;
- }
- if (strncmp(com, "Next", 4) == 0){
- if (curone != nil) {
- curone = chgaddr(1);
- buf = getpattern(curone);
- sprint(buffer,"%s/%s/%s", prog, dict, format(buf));
- wname(w, buffer);
- dispentry(w);
- }
- return True;
- }
- if (strncmp(com, "Prev",4) == 0){
- if (curone != nil) {
- curone = chgaddr(-1);
- buf = getpattern(curone);
- sprint(buffer,"%s/%s/%s", prog, dict, format(buf));
- wname(w, buffer);
- dispentry(w);
- }
- return True;
- }
- if (strncmp(com, "Nmatch",6) == 0){
- if (curaddr[++curindex] == nil)
- curindex = 0;
- curone = curaddr[curindex];
- if (curone != nil) {
- sprint(buffer,"%s/%s/%s/%d",prog,dict,format(pattern),curindex+1);
- wname(w, buffer);
- dispentry(w);
- }
- return True;
- }
- return False;
- }
- void
- handle(Win *w, int wintype)
- {
- Event e, e2, ea, etoss;
- char *s, *t, buf[80];
- int tmp, na;
- while (True) {
- wevent(w, &e);
- switch(e.c2){
- default:
- /* threadprint(2,"unknown message %c%c\n", e.c1, e.c2); */
- break;
- case 'i':
- /* threadprint(2,"'%s' inserted in tag at %d\n", e.b, e.q0);*/
- break;
- case 'I':
- /* threadprint(2,"'%s' inserted in body at %d\n", e.b, e.q0);*/
- break;
- case 'd':
- /* threadprint(2, "'%s' deleted in tag at %d\n", e.b, e.q0);*/
- break;
- case 'D':
- /* threadprint(2, "'%s' deleted in body at %d\n", e.b, e.q0);*/
- break;
- case 'x':
- case 'X': /* Execute command. */
- if (e.flag & 2)
- wevent(w, &e2);
- if(e.flag & 8){
- wevent(w, &ea);
- wevent(w, &etoss);
- na = ea.nb;
- } else
- na = 0;
- s = e.b;
- if ((e.flag & 2) && e.nb == 0)
- s = e2.b;
- if(na){
- t = malloc(strlen(s)+1+na+1);
- snprint(t, strlen(s)+1+na+1, "%s %s", s, ea.b);
- s = t;
- }
- /* if it's a long message, it can't be for us anyway */
- if(!command(s, w, wintype)) /* send it back */
- wwriteevent(w, &e);
- if(na)
- free(s);
- break;
- case 'l':
- case 'L': /* Look for something. */
- if (e.flag & 2)
- wevent(w, &e);
- wclean(w); /* Set clean bit. */
- if (wintype == Dictwin) {
- strcpy(buf, e.b);
- args[0] = lprog;
- args[1] = "-d";
- args[2] = buf;
- args[3] = nil;
- procpexec(lprog, args); /* New adict with chosen dict. */
- }
- if (wintype == Entrywin) {
- strcpy(buf, e.b);
- args[0] = lprog;
- args[1] = "-d";
- args[2] = dict;
- args[3] = buf;
- args[4] = nil;
- procpexec(lprog, args); /* New adict with chosen pattern. */
- }
- if (wintype == Matchwin) {
- tmp = atoi(e.b) - 1;
- if ((tmp >= 0) && (tmp < MAXMATCH) && (curaddr[tmp] != nil)) {
- curindex = tmp;
- curone = curaddr[curindex];
- /* Display selected match. */
- if (Eopen) {
- sprint(buf,"%s/%s/%s/%d",prog,dict,format(pattern),curindex+1);
- wname(&Ewin, buf);
- dispentry(&Ewin);
- }
- else
- procopenwin(prog,"Nmatch Prev Next", &Ewin, Entrywin);
- }
- }
- break;
- }
- }
- }
|